我想测试这个简单的后卫 canActivate和canLoad都 如何管理呢? 我第一步就是管理注入的商店
@Injectable({
providedIn: 'root'
})
export class AuthGuard implements CanActivate, CanLoad {
constructor(private store: Store<AuthState>) {}
canActivate(): Observable<boolean> {
return this.store.pipe(
select(selectIsAuthenticated),
map(isValidToken => {
if (!isValidToken) {
this.store.dispatch(new Logout());
return false;
}
return true;
}),
take(1)
);
}
canLoad(): Observable<boolean> {
return this.store.pipe(
select(selectIsAuthenticated),
map(isValidToken => {
if (!isValidToken) {
this.store.dispatch(new Logout());
return false;
}
return true;
}),
take(1)
);
}
}
我的第一步
export const authReducer: ActionReducerMap<{}> = {
status: {}
};
describe('AuthGuard', () => {
let store: Store<{}>;
beforeEach(() => {
TestBed.configureTestingModule({
imports: [StoreModule.forRoot({}).forFeature('auth', authReducer)],
providers: [Store, AuthGuard]
});
store = TestBed.get(Store);
});
it('should ...', inject([AuthGuard], (guard: AuthGuard) => {
expect(guard).toBeTruthy();
}));
});
但是测试canActivate和canLoad呢? 我要模拟选择以及如何模拟?
答案 0 :(得分:1)
请检查代码中的注释。要测试此类,您不需要TestBed。
describe('AuthGuard', () => {
let guard: AuthGuard;
let store: Subject<any> & any;
// because it's a simple class and
// we don't test templates, inputs, outputs etc,
// we can use simple objects.
beforeEach(() => {
// mocked store can be a simple BehaviorSubject.
store = new BehaviorSubject({});
// and we need a spy of course
store.dispatch = jasmine.createSpy('dispatch');
// now we can create guard
guard = new AuthGuard(store);
});
// don't forget to kill subscriptions.
afterEach(() => {
store.complete();
});
describe('canActivate', () => {
it('logouts on an empty token', () => {
// setting store state we want.
store.next({
authFeatureName: {
isLoggedIn: false,
}
});
// toBeObservable comes from https://www.npmjs.com/package/jasmine-marbles
// it's an awesome tool to test rxjs
// we expect that canActivate will emit false and close the stream - take(1).
expect(guard.canActivate()).toBeObservable(cold('a|', {
a: false,
}));
// also we need to check that an action was dispatched.
expect(store.dispatch).toHaveBeenCalledWith(jasmine.any(Logout));
});
it('returns true on valid token', () => {
// setting our store.
store.next({
authFeatureName: {
isLoggedIn: true,
}
});
// check that it emits true now
expect(guard.canActivate()).toBeObservable(cold('a|', {
a: true,
}));
// and that it doesn't dispatch any actions.
expect(store.dispatch).not.toHaveBeenCalled();
});
});
});