010*_*adm 4 unit-testing jasmine angularjs angularjs-directive
在指令中模拟$ stateParams的最佳方法是什么?$ stateParam成员将根据测试进行更改.
我可以使用$ controller('ctrl',$ stateParams)在控制器中轻松模拟$ stateParams,但不知道如何修改注入指令的$ stateParams.
我已经使用下面的装饰$ stateParams的路线,但只能在我创建模块时声明.正如我所提到的,$ stateParam成员将通过不同的测试多次更改.
beforeEach(angular.mock.module(function ($provide) {
$provide.provider('$stateParams', function () {
return {
myStateParam: true,
myOtherStateParam: 'some text'
};
});
}));
Run Code Online (Sandbox Code Playgroud)
使用指令控制器来处理与路由相关的逻辑($state/ $route)总是一个好主意,这是控制器的工作而不是链接功能.
如果一个指令可以通过测试其控制器并模拟其本地依赖性来完全测试(信用转到JB Nizet的答案),那就是故事的结尾:
$controller('...', { $scope: scope, $stateParams: { ... });
Run Code Online (Sandbox Code Playgroud)
常规指令规范并非如此$compile.内部$compile使用$controller来实例化控制器,但不接受本地模拟其依赖项.
有几种方法可以解决这个问题.
如果$stateParams不必直接注入规范并因此未实例化,则可以在模块引导后定义其值.当每个规范只应模拟一次服务实例值时,不要再看了:
var stateParams;
beforeEach(module(('...', function ($provide) {
$provide.factory('$stateParams', function () {
return stateParams;
});
}));
it('...', inject(function ($compile) {
stateParams = { ... };
...
Run Code Online (Sandbox Code Playgroud)
$provide在引导模块后,服务提供者可以作为服务实例公开(重新)定义服务:
beforeEach(module('...', function ($provide) {
$provide.value('$provide', $provide);
}));
it('...', inject(function ($provide, $compile) {
$provide.constant('$stateParams', { ... });
...
Run Code Online (Sandbox Code Playgroud)
$provide.constant在这种情况下是优选的,因为它将替换$stateParams之前注入的缓存服务实例,而$provide.value不是.
angular.copy(UI路由器0.x实际上使用它来保持$stateParams对象是最新的)可用于保留现有对象引用但替换其内容:
it('...', inject(function ($stateParams, $compile) {
angular.copy({ ... }, $stateParams);
...
Run Code Online (Sandbox Code Playgroud)
$state服务鲜为人知但尚未公开暴露于API属性params,它可以用作$stateParams代码中的服务的替代品,以提高其可测试性.
$stateParams并且$state.params可能不会引用同一个对象,因此必须选择其中一个.
代价是由于未经请求的$state注射导致测试脆弱性的风险,它可以像它一样整洁
it('...', inject(function ($state, $compile) {
$state.params = { ... };
...
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
3014 次 |
| 最近记录: |