在指令中模拟$ stateParams的最佳方法是什么? $ stateParam成员将根据测试进行更改。
我可以使用$ controller(' ctrl',$ stateParams)在控制器中轻松模拟$ stateParams,但不知道如何修改注入指令的$ stateParams。
我已经走了用下面装饰$ stateParams的路线,但只能在我创建模块时声明。正如我所提到的,$ stateParam成员将通过不同的测试多次改变。
await
答案 0 :(得分:5)
使用指令控制器来处理与路由相关的逻辑($state
/ $route
)总是一个好主意,这是控制器的工作,而不是链接功能。
如果指令可以通过测试其控制器并模拟其本地依赖关系来完全测试(积分转到JB Nizet的答案),这就是故事的结尾:
$controller('...', { $scope: scope, $stateParams: { ... });
$compile
的常规指令规范并非如此。 $compile
在内部使用$controller
来实例化控制器,但不接受本地模拟其依赖项。
有几种方法可以解决这个问题。
如果$stateParams
不必直接注入规范并因此未实例化,则可以在模块引导后定义其值。当每个规范只应模拟一次服务实例值时,不要再看了:
var stateParams;
beforeEach(module(('...', function ($provide) {
$provide.factory('$stateParams', function () {
return stateParams;
});
}));
it('...', inject(function ($compile) {
stateParams = { ... };
...
$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
服务实例,它将取代$provide.value
赢得
angular.copy
(实际上由UI路由器0.x用来保持$stateParams
对象为最新版本)可用于保留现有对象引用但替换其内容:
it('...', inject(function ($stateParams, $compile) {
angular.copy({ ... }, $stateParams);
...
$state
服务鲜为人知的publicly exposed to API属性params
,它可以用作代码中$stateParams
服务的替代品,以提高其可测试性。< / p>
$stateParams
和$state.params
可能不会引用同一个对象,因此必须选择其中一个。
以未经请求的$state
注射引起的测试脆弱性为代价,它可以像
it('...', inject(function ($state, $compile) {
$state.params = { ... };
...