Reputation: 20007
I'm trying to get started with karma-jasmine and I'm wondering why this test fails:
it("should call fakeFunction", function() {
spyOn(controller, 'addNew');
spyOn(controller, 'fakeFunction');
controller.addNew();
expect(controller.fakeFunction).toHaveBeenCalled();
});
In my controller that I've previously set up for this test I have the following:
function addNew() {
fakeFunction(3);
}
function fakeFunction(number) {
return number;
}
both addNew
and fakeFunction
are exposed using:
vm.addNew = addNew;
vm.fakeFunction = fakeFunction;
The test, however, fails with the following:
Expected spy fakeFunction to have been called.
I can make the test pass if I call the function from within my test. I was hoping, however, I could test if fakeFunction
was called by another function. What is the proper way to achieve this?
Update:
//test.js
beforeEach(function() {
module("app");
inject(function(_$rootScope_, $controller) {
$scope = _$rootScope_.$new();
controller = $controller("CreateInvoiceController", {$scope: $scope});
});
});
If I test something like:
it('should say hello', function() {
expect(controller.message).toBe('Hello');
});
The test passes if I put the following in my controller:
var vm = this;
vm.message = 'Hello';
I just want to know how I can test if a public function was called from another function.
Upvotes: 13
Views: 30052
Reputation: 802
I just came across this problem myself. The previous answer by @Vadim has the right principles but I don't think everything was very clear. In my case, I am trying to call a public function on a service from within another function. Here are the relevant snippets:
Service:
angular.module('myApp').factory('myService', function() {
function doSomething() {
service.publicMethod();
}
function publicMethod(){
// Do stuff
}
var service = {
publicMethod: publicMethod
};
return service;
});
Test:
it('calls the public method when doing something', function(){
spyOn(service, 'publicMethod');
// Run stuff to trigger doSomething()
expect(service.publicMethod).toHaveBeenCalled();
});
The key here is that the function being tested needs to be calling the same reference as the public function that is being spy'd on.
Upvotes: 10
Reputation: 17955
Your addNew
method is calling fakeFunction
. However, it is not calling controller.fakeFunction
, which is what your expectation is.
You'll need to change your code to use your controller, rather than these independent functions.
EDIT: You also need to not spy on your addNew
function. This is causing the function to be replaced with a spy. The other alternative is to change it to:
spyOn(controller, 'addNew').and.callThrough()
Upvotes: 12