Mock ngrx / store in Angular2 tests

Could you help me mock the Store? I saw this and this question having a slightly different error. I use storage in one of my services, where I use dispatching, select and retrieve storage methods. I mocked the Store after the @noelmace suggestion and used the following dispatcher, gear and state, creating the repository:

export class ObservableMock implements Observer<any> { closed?: boolean = false; // inherited from Observer nextVal: any = ''; // variable I made up constructor() { } next = (value: any): void => { this.nextVal = value; }; error = (err: any): void => { console.error(err); }; complete = (): void => { this.closed = true; } } let _reducer: ObservableMock = new ObservableMock(); let _dispatcher: ObservableMock = new ObservableMock(); let state$: Observable<any> = new Observable<any>(); 

So my Mockstore class is as follows:

 export class MockStore<T> extends Store<T> { //as given above constructor() { super(_dispatcher, _reducer, state$); } //as given above } 

However, when I try to define my service in a test as follows, it says

TypeError: _store.select is not a function

This error is caused by the following line in the TestedService constructor:

 constructor(private _store: Store<TabStore>) { let tabStore: Observable<TabStore> = _store.select<TabStore>('myReducer');| } 

Here is my test:

 beforeEach(() => { TestBed.configureTestingModule({ imports: [ // StoreModule.provideStore({myReducer: myReducer}), ], providers: [ {provide: Store, useClass: MockStore}, { provide: TestedService, useFactory: (tabStore: Store<TabStore>): TestedService=> { return new TestedService(myStore); }, deps: [Store] } ] }); }); 

Commenting on imports does not help. Does anyone have any idea what's wrong with ridicule?

+5
source share
2 answers

Finally, I found a solution to mock the store. Not sure if @maxisam's answer is right or wrong, but here is the solution I used.

 let _reducer: ObservableMock = new ObservableMock(); let _dispatcher: ObservableMock = new ObservableMock(); let state$: Observable<any> = new Observable<any>(); export class MockStore<T> extends Store<T> { private _fakeData: Object = {}; private fakeDataSubject: BehaviorSubject<Object> = new BehaviorSubject(this._fakeData); select = <T, R>(mapFn: any, ...paths: string[]): Observable<any> => { if (typeof mapFn !== 'function') { mapFn = () => mapFn; } return this.fakeDataSubject.map(mapFn); }; constructor() { super(_dispatcher, _reducer, state$); } nextMock(mock: Object, ...keys: string[]) { let curMockLevel = this._fakeData = {}; keys.forEach((key, idx) => { curMockLevel = curMockLevel[key] = idx === keys.length - 1 ? mock : {}; }); this.fakeDataSubject.next(this._fakeData); } get fakeData() { return this._fakeData; } } 

This can be used as follows:

  {provide: Store, useClass: MockStore} 
+2
source

Here is the solution I got. This is not so perfect, but it works for my case.

Basically the send method for jasmine for spyOn and validate the action is what I expect.

 export class MockStore<T> extends BehaviorSubject<T> { constructor(private _initialState: T) { super(_initialState); } dispatch = (action: Action): void => { } select = <T, R>(pathOrMapFn: any, ...paths: string[]): Observable<R> => { return map.call(this, pathOrMapFn); } nextMock(mock: T) { this.next(mock); } } 

And I use below code in providers

  { provide: Store, useValue: new MockStore({test: 'test'}) } 
0
source

Source: https://habr.com/ru/post/1266654/


All Articles