-
Notifications
You must be signed in to change notification settings - Fork 3
Mock dispatch #1
Comments
Hi! tl;dr this solution uses internals api of ngxs that might change (maybe? I don't know). Use at your own risk 😉 Starting from @uiii 's solution, I tried to create an helper function allowing me to test this easily. @Action(SetEntity)
setEntity({ patchState, dispatch }: StateContext<ConfigurationStateModel>, { entity }: SetEntity) {
patchState({
id: entity.id
});
dispatch(new AfterEntity());
} So... after a fun afternoon I came up with this: const mockNGXSState: <T>(stateClass: any) => StateContext<T> = <T>(stateClass: any) => {
const contextFactory = TestBed.get(NGXS_STATE_CONTEXT_FACTORY);
const mockStateCtx = createMockStateContext<T>(stateClass);
jest.spyOn(contextFactory, 'createStateContext').mockReturnValue(mockStateCtx);
return mockStateCtx;
};
const createMockStateContext: <T>(stateClass: any) => StateContext<T> = <T>(stateClass: any) => {
const { defaults, name } = stateClass['NGXS_OPTIONS_META'];
const store: Store = TestBed.get(Store);
return {
getState: jest.fn().mockImplementation(() => defaults),
setState: jest.fn().mockImplementation((val: T) => {
store.reset({ [name]: val });
}),
patchState: jest.fn().mockImplementation((val: Partial<T>) => {
store.reset({ [name]: { ...defaults, ...val } });
}),
dispatch: jest.fn().mockImplementation(() => of())
};
}; this allowed me to do this: describe('Configuration State', () => {
let store: Store;
let mockStateSpies;
beforeEach(() => {
TestBed.configureTestingModule({
imports: [NgxsModule.forRoot([MyState])]
});
mockStateSpies = mockNGXSState(MyState);
store = TestBed.get(Store);
store.reset({
configuration: initialConfigurationState
});
});
test('should set Entity ', () => {
const entity = {
id: '42',
label: 'foo'
};
store.dispatch(new SetEntity(entity));
const entityId = store.selectSnapshot(MyState.getId);
expect(entityId).toEqual(entity.id);
expect(mockStateSpies.dispatch).toHaveBeenCalledWith(new AfterEntity());
});
}); I think this solution can easily be used and don't use to much from the internals of the lib. The only non-public parts used are the I used Jest here but the mocks functions could easily be replaced with jasmine ones or something else. What do you think of this solution? Could this help you providing some testing helpers? |
PR's please |
Hi, I'm creating unit tests and have a problem when testing actions. I would like to mock
dispatch
function in a way it really dispatches only a tested action and any additional dispatch call are only spied.Something like this:
BUT! This doesn't work, because as I investigate, the
store.dispatch
is different from thedispatch
function in the action context. I know I can use the construction like this without mocking (and it works):BUT! I don't want to actually dispatch additional actions because of side effects. Consider the tested action dispatches an action from another module, so I would have to mock all services which causes side effects in that module.
I've found out the actual dispatch to be mocked is the one in the
InternalStateOperations
object, but I don't know how to mock it.QUESTION So what is the proper way to make tests like this?
The text was updated successfully, but these errors were encountered: