Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

AngularJS - How to test if a function is called from within another function?

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.

like image 739
Raphael Rafatpanah Avatar asked Jan 07 '15 15:01

Raphael Rafatpanah


1 Answers

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.

like image 172
Alex White Avatar answered Oct 10 '22 08:10

Alex White