Reputation: 42440
In this contrived case, I have a service that takes one dependency. The service exposes one method that needs to call through to the dependency.
If I wrap this method call in its own function, then spyOn works as expected (MyService1
). However, if I delegate to this service directly, then spyOn fails (MyService2
).
My questions are:
Thanks.
describe('spyOn problem', function() {
// wraps dependency function - can spy on
var MyService1 = function (dependency) {
this.continue = function() {
dependency.nextStage();
};
};
// delegates to dependecy function - cannot spy on
var MyService2 = function (dependency) {
this.continue = dependency.nextStage;
};
var dependencyMock = {
nextStage: function () {
}
};
it('should call nextStage method of MyService dependency', function () {
var service = new MyService1(dependencyMock);
spyOn(dependencyMock, 'nextStage'); // also tried with .andCallThrough()
service.continue();
expect(dependencyMock.nextStage).toHaveBeenCalled();
// Fail: "Expected spy nextStage to have been called"
});
it('should call nextStage method of MyService2 dependency', function () {
var service = new MyService2(dependencyMock);
spyOn(dependencyMock, 'nextStage');
service.continue();
expect(dependencyMock.nextStage).toHaveBeenCalled();
// Pass
});
});
Upvotes: 0
Views: 578
Reputation: 926
Jasmine Spies works on the objects, which means for spyOn(dependencyMock, 'nextStage')
, the function nextStage
on the object dependencyMock
will be replaced with a jasmine spy function with this statement.
In MyService2
test case, the spy is installed after actually assigning the function nextStage
to continue
, which means continue
will refer to the actual function nextStage
and not to spy. By modifying the test case as below, the spy will be assigned instead.
it('should call nextStage method of MyService2 dependency', function () {
spyOn(dependencyMock, 'nextStage');
var service = new MyService2(dependencyMock);
service.continue();
expect(dependencyMock.nextStage).toHaveBeenCalled();
// Pass
});
In the MyService1
test case, even though you are calling service.continue()
, it internally operates on 'dependencyMask` object for which spy is installed.
Upvotes: 2