我试图了解如何使用jasmine和angularJS测试我的代码。我用控制器和注入服务编写了一个测试项目。现在我想测试控制器并试图模拟注入的服务。但我没有找到一种方法来测试我的控制器“到达”功能。这是我的jsfiddle: http://jsfiddle.net/2fwxS/
controller.js:
angular.module('myApp.controllers', [])
.controller('MyCtrl', ['$scope', 'MyService', function ($scope, MyService) {
$scope.User = {};
$scope.HasUserArrived = false;
$scope.Arrived = function(firstname, lastname) {
$scope.HasUserArrived = MyService.Arrive(firstname, lastname);
return $scope.HasUserArrived;
}
}]);
services.js:
var myApp = angular.module('myApp.services', []).
value('version', '0.1');
myApp.factory('MyService', [function () {
return {
HasArrived: false,
Arrive: function (firstname, lastname) {
this.HasArrived = false;
if (firstname && lastname) {
this.HasArrived = true;
}
console.log("User has arrived: " + this.HasArrived);
return this.HasArrived;
}
}
}]);
我发现了一些类似的解释,其中$ provide可能是正确的解决方案(How can I write jasmine test for angular controller and service like this?)或createSpy(How do you mock Angular service that is a function?),但我无法理解何时需要$ provider.factory或$ provider .value或何时应该使用createSpy?
如果有人能帮助我理解差异并获取我的jsFiddle( http://jsfiddle.net/2fwxS/ )示例中已停用的代码,我将不胜感激。
答案 0 :(得分:10)
您应该使用$provide.value
以使用模拟的服务实例替换原始服务实例:
beforeEach(module(function($provide) {
var service = {
Arrive: function (firstname, lastname) {
if (firstname && lastname) {
return true;
}
}
};
$provide.value('MyService', service);
}));
我真的不知道为什么$provide.value
有效但$provide.factory
没有。我稍后会试着看一下Angular代码,这样我就可以搞清楚了。如果我发现了什么,我会更新这个答案。
关于间谍,你应该使用它们,如果你想测试你的模拟是否按照预期的方式使用。这包括检查参数和调用。这是您的代码更改为使用间谍:
it('checks that Arrived is correctly used', function() {
// Arrange
spyOn(service, 'Arrive');
// Act
scope.Arrived('Franz', 'Kafka');
// Assert
expect(service.Arrive).toHaveBeenCalledWith('Franz', 'Kafka');
});
这是你固定的jsFiddle。