I'm finding that testing an observable is causing this Karma 'it' test to be run twice. The first fails and the second passes.
I'm using a service that gets and sets the router's query parameters. It is storing the state of the app on the URL. I want to test that the state is getting stored properly. The test uses RouterTestingModule. Unless I am mistaken (likely) I shouldn't have to create my own mock router object.
I have found this post especially helpful for using done()
with a service inject.
Below is my test setup.
import {inject, TestBed } from '@angular/core/testing';
import { ArQueryService } from './ar-query.service';
import { Router, ActivatedRoute} from '@angular/router'
import { RouterTestingModule } from '@angular/router/testing';
fdescribe('ArQueryService', () => {
let service: ArQueryService;
let router: Router;
let route: ActivatedRoute;
let queryParamsDefault: Object;
beforeEach(() => {
TestBed.configureTestingModule({
providers: [ ArQueryService ],
imports: [ RouterTestingModule ]
})
service = TestBed.inject(ArQueryService);
router = TestBed.get(Router)
route = TestBed.get(ActivatedRoute)
queryParamsDefault = {
includeRealtime: true,
onlyBGC: false,
onlyDeep: false,
arHourRange: [-18, 18],
arDate: "2010-01-01T00",
displayGlobally: true
}
});
The test below injects the service and inputs a done
. The test, located inside Observable checks that the query parameter keys are the same as those set in the TestBed configuration. I'm supposed to include the done()
after all the tests have been described, otherwise, the tests will be skipped.
it('should set url with state', done => {
const queryParamsDefaultKeys = Object.keys(queryParamsDefault)
inject([ArQueryService], (service: ArQueryService) => {
service.setURL()
route.queryParamMap.subscribe( params => {
const equal = params.keys === queryParamsDefaultKeys
console.log('equal:', equal)
console.log(queryParamsDefaultKeys, params.keys)
if (params.keys.length == 0 ) {
console.log('no parameters set. not testing')
}
else {
console.log('here be parameter keys')
expect(params.keys).toEqual(queryParamsDefaultKeys)
}
done();
})
})();
});
What is strange is that this is getting run twice. The first round fails since the router does not have query parameters. The second does and passes.
What is probably happening is the first round occurs from calling setURL()
. After the params are set, the second round is run and passes.
My dirty hack is to check if there are any query params before testing. Does anyone know of a better way? I'd like to run this test once after the query parameters have been set.
Thank you in advance!