真正嘲讽的供应商 [英] Truly mocking providers
问题描述
所以基本上有关于如何忽略对模块的config /运行/提供商块,而不做一些文件加载顺序为黑客单元测试的信息。假设如下:
So basically there's no information on how to omit config/run/provider blocks on modules without doing some file load ordering hack for unit-tests. Assume the following:
// dependency chain for providers:
// aaa <- bbb <- ccc
angular.module('module0').provider('bbb', [
'aaaProvider',
function (aaaProvider) {
// aaaProvider definition
...
});
angular.module('module1').provider('ccc', [
'bbbProvider',
function (bbbProvider) {
// bbbProvider definition
...
});
angular.module('module1').controller('controller', [
function () {
// controller definition
}]);
现在假设我们正在编写一个单元测试控制器
。我们将如何做呢?
Now assume that we are writing a unit test for controller
. How would we do that?
module('module1');
inject(function ($controller, $rootScope) {
...
});
哎呀,我们有一个问题。 模块(模块1')
将触发提供商定义 CCC
,即对 BBB依赖
,即对 AAA
依赖。所以,除非我们为prevent提供商定义 CCC
被触发模块1
,我们将在运行code,它无关与控制器
我们的单元测试。
Oops, we have a problem. module('module1')
will trigger provider definition for ccc
, that has dependency on bbb
, that has dependency on aaa
. So unless we prevent provider definition for ccc
being triggered on module1
, we will running code that has nothing to do with the controller
we are unit testing.
我们可以模拟 BBB
使用模块(函数($提供){...});
符号而这样,我们就不需要加载模块0
的。
We can mock bbb
by using module(function ($provide) { ... });
notation and that way we won't need to load module0
at all.
但是,这并没有解决它 CCC
。有没有办法让我停止运行了。
But that doesn't solve it for ccc
. There's no way for me to stop it from running.
问:有没有办法从运行 CCC定义
模块1 >供应商,其中有无关控制器
我们是单元测试?
Question: Is there a way to stop module1
from running the definition of ccc
provider, which has nothing to do with controller
we are unit testing?
事情到目前为止,我已经试过:
Things I've tried so far:
-
在单元测试覆盖的定义:
Override definition in unit test:
angular.module('模块1')提供商('CCC',[功能(){}]);
推荐答案
首先,你需要在你的app.js创建两个模块
First you need to create in your app.js two modules
module1internal - 这个模块将不会有依赖性和将被用于所有
您的应用程序提供商
module1internal - this module will not have dependencies and will be used for all your application providers
angular.module('module1internal', []);
模块1 - 这个模块依赖于module1internal,将包括所有其他的依赖,配置和运行块
module1 - this module depends on the module1internal and will include all other dependencies, config and run block
angular.module('module1', ['module1internal','bbbProvider']);
在您的应用程序,你应该只使用内部模块,例如,而不是
in your app you should use only the internal module for example instead of
angular.module('module1').controller('controller', [
function () {
// controller definition
}]);
你应该使用
angular.module('module1internal').controller('controller', [
function () {
// controller definition
}]);
该测试将是这样的:
The tests will look like this:
'use strict';
describe('Controller: TheController', function () {
// mock second level dependencies
beforeEach(function () {
module('module1internal');
module({
bbb: {}
});
});
var TheController, scope,
cccMock;
// mock injected providers
beforeEach(inject(function (_ccc_) {
cccMock = mock(_ccc_);
}));
// Initialise the controller and mock scope
beforeEach(inject(function ($controller, $rootScope) {
scope = $rootScope.$new();
TheController = $controller('TheController', {
$scope: scope
});
}));
it(' should call ccc functionA on functionThatUsesFunctionA call', function () {
TheController.functionThatUsesFunctionA("someValue");
expect(cccMock.functionA).toHaveBeenCalledWith("someValue");
});
//create spy on all provider's methods(mock it)
function mock(angularServiceToMock) {
for (var i = 0; i < Object.getOwnPropertyNames(angularServiceToMock).length; i++) {
spyOn(angularServiceToMock, Object.getOwnPropertyNames(angularServiceToMock)[i]);
}
return angularServiceToMock;
}
});
这篇关于真正嘲讽的供应商的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!