我试图了解如何使用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/)示例中启动并运行已停用的代码,我将不胜感激…
您应该使用$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.