我有以下情况:
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',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',$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',foo) { $scope.bar = foo.fn(); });
foo = { fn: function() {} }; spyOn(foo,'fn').andReturn("Foo");
然后你把这个foo作为dep来传给控制器。无需注入服务。这将工作。
另一种方式是模拟服务并注入嘲笑的服务:
beforeEach(module('app',function($provide) { var foo = { fn: function() {} }; spyOn(foo,'fn').andReturn('Foo'); $provide.value('foo',foo); }));
当你注射时,它会注入这个。
看到这里:http://plnkr.co/edit/WvUIrtqMDvy1nMtCYAfo?p=preview
茉莉2.0:
对于那些努力使答案工作的人,
茉莉花2.0和Return()成为and.returnValue()
所以例如在上面的plunker的第一次测试中:
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)