Reputation: 73
I need to test my function, but I am having difficulties.
I am not able to perform 100% coverage, my difficulty is related to the function history.pushState which is called through the function onPopState.
Can someone help me?
// This line is never being covered by my tests
this.locationStrategy.onPopState(() => {
history.pushState(null, null, url);
});
My service code:
export class MyService {
constructor(private readonly locationStrategy: LocationStrategy) { }
blockNavigator(url: string) {
history.pushState(null, null, urlAtual);
// This line is never being covered by my tests
this.locationStrategy.onPopState(() => {
history.pushState(null, null, url);
});
}
}
My service test code:
describe('MyService ', () => {
let myService: MyService;
let locationStrategyMock: LocationStrategy;
beforeEach(() => {
TestBed.configureTestingModule({
providers: [
BloqueioNavegacaoService,
{
provide: LocationStrategy,
useValue: jasmine.createSpyObj('LocationStrategy', ['onPopState'])
}
]
});
myService = getTestBed().inject(MyService);
locationStrategyMock = getTestBed().inject(LocationStrategy);
});
describe('Methods:', () => {
it('.....', () => {
spyOn(myService , 'blockNavigator').and.callThrough();
locationStrategyMock.onPopState = jasmine.createSpy()
.and.callFake(() => {
// window.history.pushState(null, null, 'url');
});
myService.blockNavigator(url);
expect(myService.blockNavigator).toHaveBeenCalledTimes(1);
expect(window.history.state).toBeNull();
expect(window.history.length).toBeGreaterThanOrEqual(0);
});
});
Upvotes: 0
Views: 1244
Reputation: 18889
I think you can take advantage of .calls.mostRecent().args[0]
to get a handle on the function argument and explicitly call that function and then assert.
Check out below, there are comments as well.
describe('MyService ', () => {
let myService: MyService;
let locationStrategyMock: LocationStrategy;
// Add this line
let mockLocationStrategy: jasmine.SpyObj<LocationStrategy>;
beforeEach(() => {
// Add this line
mockLocationStrategy = jasmine.createSpyObj('LocationStrategy', ['onPopState']);
TestBed.configureTestingModule({
providers: [
BloqueioNavegacaoService,
{
provide: LocationStrategy,
// change useValue here
useValue: mockLocationStrategy
}
]
});
myService = getTestBed().inject(MyService);
locationStrategyMock = getTestBed().inject(LocationStrategy);
});
describe('Methods:', () => {
it('.....', () => {
// This line is not needed, we call it explicitly
// spyOn(myService , 'blockNavigator').and.callThrough();
myService.blockNavigator(url);
// This line is not needed, we call it explicitly (asserting nothing)
// expect(myService.blockNavigator).toHaveBeenCalledTimes(1);
// get a handle of the function (first argument) of onPopState
// when it is called (i.e. () => {
// history.pushState(null, null, url);
// }
const callBackFunction = mockLocationStrategy.onPopState.calls.mostRecent().args[0];
// Call the function
callBackFunction();
// Hopefully the bottom assertions work
expect(window.history.state).toBeNull();
expect(window.history.length).toBeGreaterThanOrEqual(0);
});
});
Upvotes: 1