I need to write unit test to Angular Router resolver. I wrote a unit test for creation, but I don't know how to test the return value and got stuck in it.
Resolver that used for getting info for component
@Injectable
export class InfoResolver implements Resolve<any> {
constructor(private readonly http: HttpClient, private readonly store: Store<IAppState>) {}
resolve(route: ActivatedRouteSnapshot): any {
const a$ = this.store.pipe(select(a));
const b$ = this.store.pipe(select(b));
return combineLatest([a$, b$]).pipe(
take(1),
map(([a, b]) => {
return a && !(b && route.paramMap.get(id) === 2)
? this.http.get('/url')
: of(false)
})
)
}
}
Unit test for creation of the resolver
const state = {
a: true,
b: false
}
describe('InfoResolver', () => {
let resolver: InfoResolver
let route = {
paramMap: {
get: (id) => 1
}
}
beforeEach(async() => {
TestBed.configureTestingModule({
providers: [InfoResolver, provideMockStore({ state })]
})
resolver = TestBed.inject(InfoResolver)
})
it('should create', () => {
expect(resolver).toBeTruthy()
})
})
How can I test the return value of resolve method?
CodePudding user response:
You should import HttpClientTestingModule
if you're injecting HttpClient
so you don't actually make Http calls in your unit test.
To unit test, I would directly call the resolve method and subscribe to it as shown in the 2nd test.
import { HttpClientTestingModule } from '@angular/common/http/testing';
....
const state = {
a: true,
b: false
}
describe('InfoResolver', () => {
let resolver: InfoResolver
let route = {
paramMap: {
get: (id) => 1
}
}
beforeEach(async() => {
TestBed.configureTestingModule({
// add this to imports array
imports: [HttpClientTestingModule],
providers: [InfoResolver, provideMockStore({ state })]
})
resolver = TestBed.inject(InfoResolver)
})
it('should create', () => {
expect(resolver).toBeTruthy()
})
// new test
it('should return xyz if abc', (done: DoneFn) => {
resolver.resolve(route).subscribe(result => {
expect(result).toBeTruthy();
// do other assertions
done(); // call done to tell jasmine you're done with the test
});
});
})
CodePudding user response:
You have already arranged an ActivatedRouteSnapshot
argument and a mock store, all that is left to do is arranging a mock http, then invoking resolve
and subscribing to it.
Since your observable behaves in a sync manner, you can safely call expect
within callback to make assertions (e.g. given that a is true, b is false and id is 1, observable returned by resolve
is expected to emit whatever data you have set for mock http).