我有一个包含方法的服务,调用时将调度一个 Action
export default class AuthService {
constructor(private store: Store<IAppState>, private jwtService: JWTService) {}
public isSessionValid = (id_token?: string, access_token?: string): Observable<boolean> => {
const hasValidSession: boolean = this.jwtService.isTokenValid(id_token);
if (!hasValidSession) {
this.invalidateSession();
return of(false);
}
this.setupValidSession(id_token, access_token);
return of(true);
}
public invalidateSession = (): void => {
this.store.dispatch(new InvalidSession());
}
public setupValidSession = (id_token?: string, access_token?: string): void => {
this.store.dispatch(new ValidSession());
if (id_token && access_token) {
this.store.dispatch(
new PersistSessionTokens({
[ID_TOKEN_STORAGE_KEY]: id_token,
[ACCESS_TOKEN_STORAGE_KEY]: access_token,
})
);
}
}
}
我想在我的测试中断言,如果
invalidateSession
被调用,一个 Action 被分派(dispatch)。然而,我尝试编写测试返回
Expected spy dispatch to have been called.
我的规范文件
import { TestBed } from '@angular/core/testing';
import { CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';
import AuthService from './auth.service';
import JWTService from '../jwt/jwt.service';
import { Store } from '@ngrx/store';
describe('AuthService', () => {
describe('isSessionValid', () => {
it('should call isTokenValid on the jwtService with an id_token', () => {
const { authService, jwtService, props } = setup({ id_token: '123' });
const jwtServiceSpy = spyOn(jwtService, 'isTokenValid');
authService.isSessionValid(props);
expect(jwtServiceSpy).toHaveBeenCalledWith({ id_token: '123' });
});
it('should call invalidateSession if hasValidSession is false', () => {
const { authService, jwtService, props } = setup({});
spyOn(jwtService, 'isTokenValid').and.returnValue(false);
const authServiceInvalidSessionSpy = spyOn(authService, 'invalidateSession');
authService.isSessionValid(props);
expect(authServiceInvalidSessionSpy).toHaveBeenCalled();
});
it('should call setupValidSession if hasValidSession is true', () => {
const { authService, jwtService, props } = setup({});
spyOn(jwtService, 'isTokenValid').and.returnValue(true);
const authServicehasValidSessionSpy = spyOn(authService, 'setupValidSession');
authService.isSessionValid(props);
expect(authServicehasValidSessionSpy).toHaveBeenCalled();
});
});
describe('invalidateSession', () => {
it('should dispatch the InvalidSession action', () => {
const { authService, jwtService, props, store } = setup({});
spyOn(jwtService, 'isTokenValid').and.returnValue(false);
const authServiceInvalidSessionSpy = spyOn(authService, 'invalidateSession');
const storeSpy = spyOn(store, 'dispatch');
authService.invalidateSession();
expect(storeSpy).toHaveBeenCalled();
});
});
const setup = propOverrides => {
TestBed.configureTestingModule({
providers: [
AuthService,
{
provide: JWTService,
useClass: MockJWTService,
},
{ provide: Store, useClass: MockStore },
],
schemas: [CUSTOM_ELEMENTS_SCHEMA],
}).compileComponents();
const props = Object.assign({}, { ...propOverrides });
const authService = TestBed.get(AuthService);
const jwtService = TestBed.get(JWTService);
const store = TestBed.get(Store);
return { authService, jwtService, props, store };
};
});
export class MockJWTService {
isTokenValid(id_token?: string) {}
}
export class MockStore {
select() {}
dispatch() {}
}
我试图在
invalidateSession
中测试它描述块
最佳答案
在你的例子中,问题是你 mock 了 spyOn(authService, 'invalidateSession');
,因此它的原始逻辑没有被调用,因此没有调度。
对于此类测试,我通常使用 ng-mocks
它允许通过几次调用来设置模拟环境。
beforeAll(() => MockBuilder(
AuthService,
[AuthServiceModule, StoreModule.forRoot({})],
));
it('dispatches an action', () => {
const dispatchSpy = MockInstance(
Store,
'dispatch',
jasmine.createSpy(),
);
const service = TestBed.inject(AuthService);
const store = TestBed.inject(Store);
service.invalidateSession();
expect(dispatchSpy).toHaveBeenCalledWith(
new InvalidSession(),
);
});
关于angular - ngrx 测试方法调度 Action ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50860228/