Last active
March 19, 2021 19:47
-
-
Save Tuizi/e2842f6ce8cd8bec58df99ef7ec42f9a to your computer and use it in GitHub Desktop.
MockStore for Angular ngrx/store unit tests
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<div class="value" *ngIf="isAdmin$ | async"> | |
{{'ACCOUNT.ROLE_ADMIN' | translate}} | |
</div> | |
<div class="value" *ngIf="!(isAdmin$ | async)"> | |
{{'ACCOUNT.ROLE_COLLABORATOR' | translate}} | |
</div> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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'); | |
}); | |
}); | |
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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) | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Thanks @Tuizi, this is what I am looking for.