注入一个angularjs控制器测试的模拟服务
我想测试一个控制器,这取决于我自己建立的服务。我想嘲笑这项服务,因为服务与DOM对话。注入一个angularjs控制器测试的模拟服务
这是我目前的测试:
describe('Player Controllers', function() {
beforeEach(function() {
this.addMatchers({
toEqualData: function (expected) {
return angular.equals(this.actual, expected);
}
});
});
describe('TestPSPlayerModule', function() {
var $httpBackend, scope, ctrl;
beforeEach(module('PSPlayerModule'));
beforeEach(inject(function (_$httpBackend_, $rootScope, $controller) {
$httpBackend = _$httpBackend_;
scope = $rootScope.$new();
ctrl = $controller(PlayerController, { $scope: scope });
}));
it('should request a clip url from the server when clipClicked is called', function() {
expect(1).toBe(1);
});
});
});
我的控制器看起来是这样的:
w.PlayerController = function ($scope, $http, $window, speedSlider, $location) {
...
}
所以这是我想嘲笑speedSlider。
我有主意,用一个模块我在测试代码创建了一个可以提供伪造的实施速度滑块,所以我增加了以下的test.js文件的顶部:
module('TestPSPlayerModule', []).factory('speedSlider', function() {
return = {
...
};
});
,然后列出在beforeEach该模块()调用,而不是具体的一个,但如果我这样做,我得到以下错误:
Injector already created, can not register a module!
所以我想一定有给我提供了一个更好的办法模拟执行我的一项服务。我可以使用sinon.js作为...
确保在您使用模块后,您没有额外的括号。所以module('TestPSPlayer')
而不是module('TestPSPlayer',[])
。
还要确保你不试图做到这一点的注入函数调用内:
这将引发错误:
beforeEach(inject(function(someOtherService) {
module('theApp', function($provide) {
myMock = {foo: 'bar'};
$provide.value('myService', myServiceMock);
someOtherService.doSomething();
});
}));
这不会:
beforeEach(function() {
module('theApp', function($provide) {
myMock = {foo: 'bar'};
$provide.value('myService', myServiceMock);
});
inject(function(someOtherService) {
someOtherService.doSomething();
});
});
更多相关imho – davidjnelson 2014-10-11 02:01:25
嵌套'module( )'inject()'里面'不是导致错误的原因。实际上,所有的'module()'调用都必须是_before_'inject()'。 – 2014-11-18 10:15:49
@HermanKan为什么? – tobi 2015-04-14 05:38:25
在我的情况这没有奏效:
beforeEach(module('user'));
beforeEach(inject(function ($http) {
}));
beforeEach(module('community'));
beforeEach(inject(function ($controller, $rootScope) {
}));
我已经改变了这使它的工作:
beforeEach(module('user'));
beforeEach(module('community'));
beforeEach(inject(function ($http) {
}));
beforeEach(inject(function ($controller, $rootScope) {
}));
这解释了应该在所有模块初始化之后调用注入 – 2016-05-31 10:56:20
如果您的提供商不使用全局初始化,您可以使用原来的注射提供商和嘲笑它。在下面的示例中,是您的控制器。
var injectedProviderMock;
beforeEach(function() {
module('myModule');
});
beforeEach(inject(function (_injected_) {
injectedProviderMock = mock(_injected_);
}));
var testedProvider;
beforeEach(inject(function (_testedProvider_) {
testedProvider = _testedProvider_;
}));
it("return value from injected provider", function() {
injectedProviderMock.myFunc.andReturn('testvalue');
var res = testedProvider.executeMyFuncFromInjected();
expect(res).toBe('testvalue');
});
//mock all provider's methods
function mock(angularProviderToMock) {
for (var i = 0; i < Object.getOwnPropertyNames(angularProviderToMock).length; i++) {
spyOn(angularProviderToMock,Object.getOwnPropertyNames(angularProviderToMock)[i]);
}
return angularProviderToMock;
}
你见过这个文档吗? http://docs.angularjs.org/guide/dev_guide.services.testing_services其中'$ window'被嘲笑。这是一个相当简单的例子,但它可能为您想要做的事提供模板。 – 2012-07-12 22:31:05
@NoahFreitas你提供的链接现在已经死亡 – Stephane 2015-04-11 14:35:53
@StephaneEybert,看起来它已被移动并更新到这里:https://docs.angularjs.org/guide/services#unit-testing – 2015-04-11 18:01:14