Skip to content

Instantly share code, notes, and snippets.

@Tuizi
Last active March 19, 2021 19:47
Show Gist options
  • Star 14 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save Tuizi/e2842f6ce8cd8bec58df99ef7ec42f9a to your computer and use it in GitHub Desktop.
Save Tuizi/e2842f6ce8cd8bec58df99ef7ec42f9a to your computer and use it in GitHub Desktop.
MockStore for Angular ngrx/store unit tests
import { Action, ActionReducer, Store } from '@ngrx/store';
import { BehaviorSubject } from 'rxjs/BehaviorSubject';
import { Observable } from 'rxjs/Observable';
import { map } from 'rxjs/operator/map';
import { Observer } from 'rxjs/Observer';
// TODO: How to initialize those variables?
const dispatcherMock: Observer<Action>,
reducerMock: Observer<ActionReducer<any>>,
stateMock: 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<R> => {
return map.call(this.fakeDataSubject, mapFn);
};
constructor() {
super(dispatcherMock, reducerMock, stateMock);
}
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;
}
}
<div class="value" *ngIf="isAdmin$ | async">
{{'ACCOUNT.ROLE_ADMIN' | translate}}
</div>
<div class="value" *ngIf="!(isAdmin$ | async)">
{{'ACCOUNT.ROLE_COLLABORATOR' | translate}}
</div>
describe('TestComponent', () => {
let comp: TestComponent;
let fixture: ComponentFixture<TestComponent>;
let nativeElement: any;
beforeEach(() => {
TestBed.configureTestingModule({
declarations: [
TestComponent,
],
schemas: [NO_ERRORS_SCHEMA],
providers: [
{provide: Store, useClass: MockStore},
]
});
fixture = TestBed.createComponent(TestComponent);
comp = fixture.componentInstance;
nativeElement = fixture.debugElement.nativeElement;
});
beforeEach(inject([Store], (store: MockStore<AppState>) => {
store.nextMock({
isAdmin: false
}, 'account');
}));
it('can load instance', () => {
expect(comp).toBeTruthy();
fixture.detectChanges();
});
describe('Account type', () => {
it('should display role collaborator', () => {
fixture.detectChanges();
expect(nativeElement.querySelector('.value').innerText).toBe('ACCOUNT.ROLE_COLLABORATOR');
});
it('should display role admin', () => {
const injectedStoreStub = fixture.debugElement.injector.get(Store) as MockStore<AppState>;
injectedStoreStub.nextMock({
isAdmin: true,
}, 'account');
fixture.detectChanges();
expect(nativeElement.querySelector('.value').innerText).toBe('ACCOUNT.ROLE_ADMIN');
});
});
});
import { Component } from '@angular/core';
import { AppState } from '../../core/store/reducers';
import { Store } from '@ngrx/store';
@Component({
selector: 't-test',
templateUrl: 'test.component.html',
styleUrls: ['test.component.css']
})
export class TestComponent {
isAdmin$: Observable<boolean>;
constructor(private store: Store<AppState>) {
this.isAdmin$ = this.store.select(state => state.account.isAdmin)
}
}
@thlinhit
Copy link

Thanks @Tuizi, this is what I am looking for.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment