Search code examples
angularjsunit-testingmeteorjasmineangular-mock

Jasmine spyOn on function and returned object


I'm using MeteorJS with angular and want to test controller. My controller use $reactive(this).attach($scope). I need to check, if this method was called.

I create something like that for spy:

var $reactive = function(ctrl) {
    return {
        attach:function(scope) {}
    }
};

So I can call it like that:

$reactive('aaa').attach('bbb');

How I can do it in tests?

spyOn($reactive, 'attach');

Doesn't work. I got Error: attach() method does not exist

And how to check if it was called? This is good call?

expect($reactive).toHaveBeenCalledWith(controller);

And how to check that function attach was called with args (scope)?


Solution

  • You'll need to mock the $reactive component. Replace it with a spy that returns an spyObj in the scope of the test. Then trigger what ever makes the $reactive method to run and test.

    var reactiveResult = jasmine.createSpyObj('reactiveResult', ['attach']);
    var $reactive = jasmine.createSpy('$reactive').and.returnValue(reactiveResult);
    var controller = {};
        beforeEach(function () {
          module(function ($provide) {
            $provide.factory('$reactive', $reactive);
          });
          module('yourAppModule');
        });
    
    it('Should call attach', function () {
      $reactive(controller).attach();
      expect($reactive).toHaveBeenCalledWith(controller);
      expect(reactiveResult.attach).toHaveBeenCalled();
    }) ;
    

    You can provide the $reactive spy to the controller dependencies too:

    var reactiveResult = jasmine.createSpyObj('reactiveResult', ['attach']);
    var $reactive = jasmine.createSpy('$reactive').and.returnValue(reactiveResult);
    var ctrl;
        beforeEach(inject(function ($controller) {
          ctrl = $controller('YourController', {$reactive: $reactive });
        }));
    
    it('Should call attach', function () {
      //ctrl.triggerThe$reactiveCall
      expect($reactive).toHaveBeenCalledWith(ctrl);
      expect(reactiveResult.attach).toHaveBeenCalled();
    }) ;