在指令中模拟 $stateParams 的最佳方法是什么? $stateParam 成员会根据测试而改变。
我可以使用 $controller('ctrl', $stateParams) 在 Controller 中轻松模拟 $stateParams,但不知道如何修改注入(inject)指令的 $stateParams。
我已经用下面的方法装饰了 $stateParams 但只能在我创建模块时声明。正如我所提到的,$stateParam 成员将通过不同的测试多次更改。
beforeEach(angular.mock.module(function ($provide) {
$provide.provider('$stateParams', function () {
return {
myStateParam: true,
myOtherStateParam: 'some text'
};
});
}));
最佳答案
使用指令 Controller 来处理与路由相关的逻辑( $state
/$route
)总是一个好主意,这是 Controller 的工作,而不是链接功能。
对于可以通过测试其 Controller 并模拟其本地依赖项来完全测试的指令(信用转到 JB Nizet 的回答),故事就结束了:
$controller('...', { $scope: scope, $stateParams: { ... });
$compile
的常规指令规范并非如此. $compile
使用 $controller
在内部实例化 Controller ,但不接受本地人来模拟其依赖关系。有几种方法可以处理这个问题。
$provide.factory
如果
$stateParams
不必直接注入(inject)到规范中,因此没有实例化,它的值可以在模块引导后定义。当每个规范只应该模拟一次服务实例值时,不要再看了:var stateParams;
beforeEach(module(('...', function ($provide) {
$provide.factory('$stateParams', function () {
return stateParams;
});
}));
it('...', inject(function ($compile) {
stateParams = { ... };
...
$provide.constant
$provide
服务商can be exposed as service instance在模块被引导后(重新)定义服务:beforeEach(module('...', function ($provide) {
$provide.value('$provide', $provide);
}));
it('...', inject(function ($provide, $compile) {
$provide.constant('$stateParams', { ... });
...
$provide.constant
在这种情况下更可取,因为它将替换缓存的 $stateParams
服务实例,如果它之前被注入(inject),而 $provide.value
惯于。Angular 复制
angular.copy
(UI Router 0.x 实际上使用它来保持 $stateParams
对象最新)可用于保留现有对象引用但替换其内容:it('...', inject(function ($stateParams, $compile) {
angular.copy({ ... }, $stateParams);
...
$state.params
$state
服务鲜为人知publicly exposed to API房产 params
,它可以用作$stateParams
的替代品服务所有代码以提高其可测试性。$stateParams
和 $state.params
可能不是指同一个对象,因此必须做出有利于其中一个的选择。以不请自来的
$state
导致的测试脆弱性风险为代价注入(inject),它可以像it('...', inject(function ($state, $compile) {
$state.params = { ... };
...
关于angularjs - 指令中的 angular + jasmine + mock $stateParams,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35899581/