本文介绍了指令中的angular + jasmine + mock $ stateParams的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在指令中模拟$ stateParams的最佳方法是什么? $ stateParam成员将根据测试进行更改。

What is the best approach to mock $stateParams in a directive? $stateParam members will be changed according to the test.

我可以使用$ controller('ctrl',$ stateParams)在控制器中轻松模拟$ stateParams,但不知道如何修改注入指令的$ stateParams。

I can easily mock $stateParams in a controller using $controller('ctrl', $stateParams) but dont know how to modify $stateParams that gets injected into the directive.

我已经使用下面的装饰$ stateParams的路线,但只能在我创建模块时声明。正如我所提到的,$ stateParam成员将通过不同的测试多次更改。

I've gone the route of decorating $stateParams with the below but can only declare that when i create the module. as i mentioned, $stateParam members will change many times through the different tests.

beforeEach(angular.mock.module(function ($provide) {

    $provide.provider('$stateParams', function () {
        return {
            myStateParam: true,
            myOtherStateParam: 'some text'
        };
    });

}));


推荐答案

使用指令控制器处理与路径相关的逻辑( $ state / $ route )总是一个好主意,这是控制器的工作而不是链接功能。

Using directive controller to handle route-related logic ($state/$route) is always a good idea, that's the job for controller and not for linking functions.

如果指令可以通过测试其控制器并模拟其本地依赖关系来完全测试(积分转到JB Nizet的回答)它故事的结尾:

In the case of a directive that could be tested completely just by testing its controller and mocking its local dependencies (credits go to JB Nizet's answer) it is the end of the story:

$controller('...', { $scope: scope, $stateParams: { ... });

对于带有 $ compile的常规指令规范,情况并非如此 $ compile 在内部使用 $ controller 来实例化控制器,但不接受本地模拟其依赖项。

It isn't the case for regular directive spec with $compile. $compile uses $controller internally to instantiate the controller but doesn't accept locals to mock its dependencies.

有几种方法可以解决这个问题。

There are several ways to handle this.

如果 $ stateParams 不必直接注入规范并因此未实例化,则可以在模块引导后定义其值。当每个规范只应模拟一次服务实例值时,不要再看了:

If $stateParams does not have to be injected into spec directly and thus is uninstantiated, its value can be defined after the module was bootstrapped. When service instance value should be mocked only once per spec, look no further:

var stateParams;

beforeEach(module(('...', function ($provide) {
    $provide.factory('$stateParams', function () {
        return stateParams;
    });
}));

it('...', inject(function ($compile) {
  stateParams = { ... };
  ...



$ provide.constant



$ provide 服务提供商在模块引导后(重新)定义服务:

$provide.constant

$provide service provider can be exposed as service instance to (re)define services after the module was bootstrapped:

beforeEach(module('...', function ($provide) {
  $provide.value('$provide', $provide);
}));

it('...', inject(function ($provide, $compile) {
  $provide.constant('$stateParams', { ... });
  ...

$ provide.constant 在这种情况下更可取,因为它将取代缓存的 $ stateParams 服务实例,如果它之前被注入,whi le $ provide.value 不会。

$provide.constant is preferable in this case because it will replace cached $stateParams service instance if it was injected before, while $provide.value won't.

angular.copy (UI路由器0.x实际上使用它来保持 $ stateParams 对象最新的)可用于保留现有的对象引用但替换其内容:

angular.copy (which actually was used by UI Router 0.x to keep $stateParams object up to date) can be used to preserve existing object references but replace its contents:

it('...', inject(function ($stateParams, $compile) {
  angular.copy({ ... }, $stateParams);
  ...



$ state.params



$ state 服务鲜为人知属性 params ,它可以用作在整个代码中替换 $ stateParams 服务以提高其可测试性。

$state.params

$state service has little-known yet publicly exposed to API property params, it can be used as a replacement for $stateParams service all over the code to improve its testablity.

$ stateParams $ state.params 可能不会引用同一个对象,因此必须选择其中一个。

$stateParams and $state.params may not refer to the same object, so the choice has to be made in favour of one of them.

由于未经请求的 $ state 注入导致测试脆弱的风险,它可以像

At the cost of the risk of test fragility due to of unsolicited $state injection, it can be as neat as

it('...', inject(function ($state, $compile) {
  $state.params = { ... };
  ...

这篇关于指令中的angular + jasmine + mock $ stateParams的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

10-25 04:34