模拟服务返回承诺:无法读取未定义的 属性
Mocked service returning promise: Cannot read property of undefined
我正在使用 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();
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();
});
以上两个测试都失败了。对于第一个,错误是:Cannot read property of undefined
,对于第二个:expected spy sendMsg to have been called
。第一个错误发生在:app.js 文件,如调用堆栈所示。我还使用 karma chrome window 中的 Debug 选项调试了我的测试。 printData()
函数正在调用 app.js 中的实际代码,但我已经模拟了它。
请任何人解释一下为什么会这样以及如何解决这个问题?为什么要调用原始代码以及如何使这两个测试都通过。
Jasmine 的 spy 只检查函数是否被调用,而不触发实际的实现。这就是 getData().then
抛出错误的原因。
如您所见,on Jasmine's documentation 您需要添加 .and.callThrough()
以完成原始功能。
我认为第一个问题可能与代码中的语法错误有关 - 在第一个 it
块中,scope
变量指的是什么?
我正在使用 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();
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();
});
以上两个测试都失败了。对于第一个,错误是:Cannot read property of undefined
,对于第二个:expected spy sendMsg to have been called
。第一个错误发生在:app.js 文件,如调用堆栈所示。我还使用 karma chrome window 中的 Debug 选项调试了我的测试。 printData()
函数正在调用 app.js 中的实际代码,但我已经模拟了它。
请任何人解释一下为什么会这样以及如何解决这个问题?为什么要调用原始代码以及如何使这两个测试都通过。
Jasmine 的 spy 只检查函数是否被调用,而不触发实际的实现。这就是 getData().then
抛出错误的原因。
如您所见,on Jasmine's documentation 您需要添加 .and.callThrough()
以完成原始功能。
我认为第一个问题可能与代码中的语法错误有关 - 在第一个 it
块中,scope
变量指的是什么?