dimanche 6 décembre 2015

Mocked service returning promise: Cannot read property of undefined

I am doing unit testing using karma and jasmine. I have app.js as main source file:

app.service("someServ", function(){
  this.sendMsg = function(name){
    return "Hello " + name;
  }
})

app.factory("appFactory", function ($q, someServ) {
  function getData() {
    var defer = $q.defer();
    defer.resolve("Success message");
    return defer.promise;
} 

function foo(){
    var text = someServ.sendMsg("Message");
    alert(text);
}
return {
    getData : getData,
    foo : foo
}
})

app.controller("mainController",['$scope','$http','appFactory',function($scope, $http, appFactory){
var mct = this;
mct.printData = function(){
    var myPromise = appFactory.getData();
    myPromise
        .then(function(data){
            alert("Promise returned successfully. Data : " + data);
        }, function(error){
            alert("Something went wrong.... Error: "  + error);
        })
}
mct.showMsg = function(){
    appFactory.foo();
}
}]);

My testFile.js is as follows:

   beforeEach(module(function($provide){
    $provide.service("someServ", function(){
        this.sendMsg =   jasmine.createSpy('sendMsg').and.callFake(function(param){})
    });

    $provide.factory("appFactory", function(someServ, $q){
        function getData(){
            var defer = $q.defer();
            defer.resolve("Success message");
            return defer.promise;
        }
        function foo(){
            var facParam = "some text";
            someServ.sendMsg(facParam);
        }
        return {
            getData : getData,
            foo : foo
        }
    });
}));

var $scope, mainController, appFactoryMock, someServMock;

beforeEach(inject(function($rootScope, $controller, $http, $q, appFactory, someServ){
    appFactoryMock = appFactory;
    someServMock = someServ;
    $scope = $rootScope.$new();
    mainController = $controller("mainController", {
        $scope : $scope,
        $http : $http,
        appFactory : appFactoryMock
    });

}));

it('that mainController is calling appFactory methods', function(){
    spyOn(appFactoryMock, "getData");
    mainController.printData();
    scope.$root.$digest();
    expect(appFactoryMock.getData).toHaveBeenCalled();
})

it('that appFactory method foo calls someServ sendMsg', function(){
    spyOn(appFactoryMock, "foo");
    appFactoryMock.foo();
    expect(someServMock.sendMsg).toHaveBeenCalled();
});

Both the above tests are failing. For first one, error is: Cannot read property of undefined and for second one: expected spy sendMsg to have been called. First error occurs at: app.js file as shown in call stack. I have also debugged my tests using Debug option in karma chrome window. The printData() function is calling actual code in app.js but I have already mocked it.

Please anyone explain me why is it happening so and how to solve this issue? Why original code is being called and how can I make both these tests to pass.

Aucun commentaire:

Enregistrer un commentaire