Javascript Jasmine控制器测试,预计已调用间谍
我在AngularJS控制器中定义了一个在初始化时调用的方法。我想用Jasmine(Javascript Jasmine控制器测试,预计已调用间谍,javascript,angularjs,karma-jasmine,Javascript,Angularjs,Karma Jasmine,我在AngularJS控制器中定义了一个在初始化时调用的方法。我想用Jasmine(“Jasmine core”:“^2.3.4”,“karma”:“^0.12.37”)来测试它。我在网上学习了一些教程和问题,但是我找不到正确的答案。请查看此代码: 控制器usersAddUserController: (function () { 'use strict'; angular.module('app.users.addUser') .controller('use
“Jasmine core”:“^2.3.4”,“karma”:“^0.12.37”
)来测试它。我在网上学习了一些教程和问题,但是我找不到正确的答案。请查看此代码:
控制器usersAddUserController
:
(function () {
'use strict';
angular.module('app.users.addUser')
.controller('usersAddUserController', ['$scope', 'usersAddUserService', function ($scope, usersAddUserService) {
usersAddUserService.getCountryPhoneCodes().then(function (phoneCodes) {
$scope.phoneCodes = phoneCodes;
});
}]);
}());
茉莉花试验:
(function () {
'use strict';
describe('usersAddUserControllerUnitTest', function () {
var scope, deferred, objectUnderTest, mockedAddUserService;
beforeEach(module('app'));
beforeEach(inject(function ($rootScope, $q, $controller) {
scope = $rootScope.$new();
function emptyPromise() {
deferred = $q.defer();
return deferred.promise;
}
mockedAddUserService = {
getCountryPhoneCodes: emptyPromise
};
objectUnderTest = $controller('usersAddUserController', {
$scope: scope,
usersAddUserService: mockedAddUserService
});
}));
it('should call getCountryPhoneCodes method on init', function () {
//when
spyOn(mockedAddUserService, 'getCountryPhoneCodes').and.callThrough();
deferred.resolve();
scope.$root.$digest();
//then
expect(mockedAddUserService.getCountryPhoneCodes).toHaveBeenCalled();
});
});
}());
运行测试后,错误消息为:
PhantomJS 1.9.8(Windows 7 0.0.0)usersAddUserControllerUnitTest应在init上调用getCountryPhoneCodes方法失败
Expected spy getCountryPhoneCodes to have been called.
我显然遗漏了一些东西,但我不知道是什么。任何帮助都将不胜感激。您可以提供如下模拟:
mockedAddUserService = {
getCountryPhoneCodes: emptyPromise
};
beforeEach(function () {
module(function ($provide) {
$provide.value('usersAddUserService', mockedAddUserService);
});
});
(function () {
'use strict';
describe('usersAddUserControllerUnitTest', function () {
beforeEach(module('app'));
var emptyPromise = function() {
var deferred = $q.defer();
return deferred.promise;
}
var mockedAddUserService = {
getCountryPhoneCodes: emptyPromise
};
beforeEach(function () {
module(function ($provide) {
$provide.value('usersAddUserService', mockedAddUserService);
});
});
var scope;
beforeEach(inject(function ($rootScope, $q, $controller) {
scope = $rootScope.$new();
$controller('usersAddUserController', {
$scope: scope
});
}));
it('should call getCountryPhoneCodes method on init', function () {
spyOn(mockedAddUserService, 'getCountryPhoneCodes').and.callThrough();
scope.$root.$digest();
expect(mockedAddUserService.getCountryPhoneCodes).toHaveBeenCalled();
});
});
}());
编辑:
代码应该是这样的(因为我无法测试它):
mockedAddUserService = {
getCountryPhoneCodes: emptyPromise
};
beforeEach(function () {
module(function ($provide) {
$provide.value('usersAddUserService', mockedAddUserService);
});
});
(function () {
'use strict';
describe('usersAddUserControllerUnitTest', function () {
beforeEach(module('app'));
var emptyPromise = function() {
var deferred = $q.defer();
return deferred.promise;
}
var mockedAddUserService = {
getCountryPhoneCodes: emptyPromise
};
beforeEach(function () {
module(function ($provide) {
$provide.value('usersAddUserService', mockedAddUserService);
});
});
var scope;
beforeEach(inject(function ($rootScope, $q, $controller) {
scope = $rootScope.$new();
$controller('usersAddUserController', {
$scope: scope
});
}));
it('should call getCountryPhoneCodes method on init', function () {
spyOn(mockedAddUserService, 'getCountryPhoneCodes').and.callThrough();
scope.$root.$digest();
expect(mockedAddUserService.getCountryPhoneCodes).toHaveBeenCalled();
});
});
}());
在模拟被传递到实例化的控制器之后,您正在监视它 试试这个:
describe('usersAddUserControllerUnitTest', function () {
var scope, deferred, objectUnderTest, mockedAddUserService, $controller;
beforeEach(module('app'));
beforeEach(inject(function ($rootScope, $q, _$controller_) {
scope = $rootScope.$new();
function emptyPromise() {
deferred = $q.defer();
return deferred.promise;
}
mockedAddUserService = {
getCountryPhoneCodes: emptyPromise
};
$controller = _$controller_;
}));
function makeController() {
objectUnderTest = $controller('usersAddUserController', {
$scope: scope,
usersAddUserService: mockedAddUserService
});
}
it('should call getCountryPhoneCodes method on init', function () {
//when
spyOn(mockedAddUserService, 'getCountryPhoneCodes').and.callThrough();
makeController();
deferred.resolve();
scope.$root.$digest();
//then
expect(mockedAddUserService.getCountryPhoneCodes).toHaveBeenCalled();
});
});
编辑谢谢@juunas注意到我的解决方案中的错误谢谢你的回答,但是你能提供完整的代码吗?当我在代码中包含您的解决方案时,我会得到:“TypeError:‘undefined’不是对象(评估‘deferred.resolve’)”。感谢您的代码,我也会尝试您的解决方案,并给出需要进一步做的反馈。感谢您的回答,但不幸的是,您的代码仍然会出现相同的错误。这对你有用吗?我其实没有试过,只是看起来问题很明显。你能在你的控制器构造函数上设置一个断点,看看它是否真的是它正在调用的间谍吗?非常感谢你们!的确@juunas是对的,我现在成功了。如果朱纳斯同意,我无论如何都会接受马丁的回答,这对我有很大帮助:)我不太喜欢这个解决方案的两个原因:1。您必须调用makeController();在每次测试中(可以在每次测试之前将其放入一个测试中)2。代码看起来不像“提供方法”那样直截了当,但好吧,这只是一个品味问题。:)好吧,看来你必须小心事情的顺序。我认为你在提供…@timtos方面没有这个问题,你的观点是正确的。此解决方案是从原始代码到工作测试的最短路径。