Reputation: 5357
I was under the impression that you could just spy on services in jasmine using the spyOn method. And then return a value once that method is called. But maybe that's too simplistic of a thought?
I would like to test the following nxjs action:
./Auth.state.ts
// ...
@Action(Login)
login(ctx: StateContext<AuthStateModel>, action: Login) {
return this.authService.login(action.payload).pipe(
tap(({ accessToken }: { accessToken: string }) => {
const {exp} = jwt_decode(accessToken);
const expiresAt = dayjs().add(exp, 'second');
ctx.patchState({
token: accessToken,
username: action.payload.username,
expiresAt
});
})
);
}
That action depends on the authService login method:
./auth.service.ts
// ...
login({ username, password }: User): Observable<{ accessToken?: string }> {
return this.http
.post(`${api.BASEURL}${api.API_LOGIN}`, { username, password });
}
Now my test is as follows:
./Auth.state.spec.ts
describe('Auth', () => {
let store: Store;
beforeEach(() => {
TestBed.configureTestingModule({
imports: [NgxsModule.forRoot([AuthState]), HttpClientTestingModule],
providers: [HttpClient, HttpHandler, AuthService]
});
store = TestBed.inject(Store);
});
function setupState(NEW_STATE = null) {
store.reset({
...store.snapshot(),
auth: NEW_STATE
});
}
describe('login', () => {
it('sets the state when login is successful', () => {
// TS2345: Argument of type '"register"' is not assignable to parameter of type 'never'.
spyOn(AuthService, 'login').and.returnValue(false);
// read an workaround for it here: https://github.com/facebook/jest/issues/9675
// Object.defineProperty(AuthService, 'login', { get(){ return false; } });
// but also no luck...
const expectedState = { token: null, username: 'Some username', expiresAt: null };
setupState();
store.dispatch(new Login({ username: expectedState.username, password: '' }));
const auth = store.selectSnapshot(state => state.auth);
expect(auth).toEqual(expectedState);
});
});
// ...
Upvotes: 0
Views: 1501
Reputation: 1059
In your Auth.state.spec.ts
file, you should get instance of injected service from angular's TestBed
.
describe('login', () => {
it('sets the state when login is successful', () => {
// Get the injected instance of AuthService
const authService = TestBed.inject(AuthService);
spyOn(authService, 'register').and.returnValue(of(false));
spyOn(authService, 'login').and.returnValue(
of({ access_token: 'scdkj2' })
);
// Make sure fixture.detectChanges() is not invoked before all spies are setup
fixture.detectChanges();
....
});
});
Upvotes: 1