Javascript 模拟服务返回承诺:无法读取未定义的属性
我正在使用Karma和Jasmine进行单元测试。我将app.js作为主要源文件:Javascript 模拟服务返回承诺:无法读取未定义的属性,javascript,angularjs,unit-testing,karma-jasmine,Javascript,Angularjs,Unit Testing,Karma Jasmine,我正在使用Karma和Jasmine进行单元测试。我将app.js作为主要源文件: app.service("someServ", function(){ this.sendMsg = function(name){ return "Hello " + name; } }) app.factory("appFactory", function ($q, someServ) { function getData() { var defer = $q.defer();
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();
}
}]);
我的testFile.js如下所示:
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();
});
上述两项测试均未通过。第一个错误是:无法读取未定义的
的属性,第二个错误是:预期spy sendMsg已被调用
。第一个错误出现在:app.js文件中,如调用堆栈中所示。我还使用karma chrome窗口中的调试选项调试了我的测试。printData()
函数正在调用app.js中的实际代码,但我已经模拟了它
请任何人向我解释为什么会这样,以及如何解决这个问题?调用原始代码的原因以及如何通过这两个测试。Jasmine的spy只检查函数是否已被调用,而不启动实际实现。这就是为什么
getData()。然后抛出错误
如您所知,您需要添加和.callThrough()
来完成原始函数。我相信第一个问题可能与代码中的语法错误有关-在第一个it
块中,scope
变量指的是什么?是!这是一个打字错误。scope实际上应该是$scope。谢谢。嘿@Mario,谢谢你的回复。我还有一个疑问。我的测试如下:spyOn(appFactoryMock,“getData”)。和.callThrough();$scope.$root.$digest();mainController.printData();expect(appFactoryMock.getData).toHaveBeenCalled()代码>我对调用mainController.printData()感到困惑;这实际上是在调用appFactory的getData,那么为什么我需要单独使用and.callThrough()。你相信你的appFactory会工作,因为你正在测试控制器,所以你不关心真正的实现:如果它被调用,它会工作,这就是为什么我们有间谍。那么,为什么您仍然需要模拟实现呢?调用控制器的printData
,它调用appFactory.getData
,并希望得到一个承诺作为回报:如果不使用和.callThrough
,则行myPromise。然后将中断,因为myPromise
未定义