我正在尝试测试依赖于我自己构建的服务的控制器。我想嘲笑这项服务,因为服务与DOM进行了对话。
这是我目前的测试:
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做的事情......
答案 0 :(得分:40)
另外请确保您没有尝试在注入函数调用中执行此操作:
这会抛出错误:
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();
});
});
答案 1 :(得分:6)
确保在定义后使用模块时没有额外的括号。
所以module('TestPSPlayer')
代替module('TestPSPlayer',[])
。
答案 2 :(得分:4)
就我而言,这并没有奏效:
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) {
}));
答案 3 :(得分:0)
如果您的提供者不使用全局init,您可以使用原始注入的提供者并模拟它。 在下面的示例中,measuredProvider是您的控制器。
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;
}