我有以下情况:
controller.js
controller('PublishersCtrl',['$scope','APIService','$timeout', function($scope,APIService,$timeout) { APIService.get_publisher_list().then(function(data){ }); }));
controllerSpec.js
'use strict'; describe('controllers', function(){ var scope, ctrl, timeout; beforeEach(module('controllers')); beforeEach(inject(function($rootScope, $controller) { scope = $rootScope.$new(); // this is what you missed out timeout = {}; controller = $controller('PublishersCtrl', { $scope: scope, APIService: APIService, $timeout: timeout }); })); it('should have scope variable equals number', function() { expect(scope.number).toBe(3); }); });
错误:
TypeError: Object #<Object> has no method 'get_publisher_list'
我也尝试过类似的方法,但没有成功:
describe('controllers', function(){ var scope, ctrl, timeout,APIService; beforeEach(module('controllers')); beforeEach(module(function($provide) { var service = { get_publisher_list: function () { return true; } }; $provide.value('APIService', service); })); beforeEach(inject(function($rootScope, $controller) { scope = $rootScope.$new(); timeout = {}; controller = $controller('PublishersCtrl', { $scope: scope, APIService: APIService, $timeout: timeout } ); })); it('should have scope variable equals number', function() { spyOn(service, 'APIService'); scope.get_publisher_list(); expect(scope.number).toBe(3); }); });
我该如何解决?有什么建议?
有两种方法(或肯定有更多方法)。
想象一下这种服务(无论它是工厂都没关系):
app.service('foo', function() { this.fn = function() { return "Foo"; }; });
使用此控制器:
app.controller('MainCtrl', function($scope, foo) { $scope.bar = foo.fn(); });
一种方法是使用要使用的方法创建对象并对其进行监视:
foo = { fn: function() {} }; spyOn(foo, 'fn').andReturn("Foo");
然后,将其foo作为dep传递给控制器。无需注入服务。那可行。
foo
另一种方法是模拟服务并注入模拟的服务:
beforeEach(module('app', function($provide) { var foo = { fn: function() {} }; spyOn(foo, 'fn').andReturn('Foo'); $provide.value('foo', foo); }));
当您注入时foo,它将注入这一点。
在此处查看:http : //plnkr.co/edit/WvUIrtqMDvy1nMtCYAfo?p=preview
对于那些努力使答案起作用的人,
从Jasmine 2.0 andReturn()开始and.returnValue()
andReturn()
and.returnValue()
因此,例如,在上面的unk客的第一次测试中:
describe('controller: MainCtrl', function() { var ctrl, foo, $scope; beforeEach(module('app')); beforeEach(inject(function($rootScope, $controller) { foo = { fn: function() {} }; spyOn(foo, 'fn').and.returnValue("Foo"); // <----------- HERE $scope = $rootScope.$new(); ctrl = $controller('MainCtrl', {$scope: $scope , foo: foo }); })); it('Should call foo fn', function() { expect($scope.bar).toBe('Foo'); }); });
(来源:Rvandersteen)