【问题标题】:Testing AngularJS scope variables测试 AngularJS 范围变量
【发布时间】:2013-12-09 22:59:58
【问题描述】:

我正在尝试实现一个依赖于范围变量的测试。我想启用 ng-switch-when 来解析表达式。这就是我想要做的(UPDATE 使用 $rootScope):

it('should switch on array changes', inject(function($rootScope, $compile) {
  element = $compile(
    '<div ng-switch="select">' +
      '<div ng-switch-when="test[0]">test[0]:{{test[0]}}</div>' +
    '</div>')($rootScope);
  expect(element.html()).toEqual('<!-- ngSwitchWhen: test[0] -->');
  $rootScope.test = ["leog"];
  $rootScope.select = "leog";
  $rootScope.$apply();
  expect(element.text()).toEqual('test[0]:leog');
}));

我的问题是 我为此工作的实现没有得到范围变量“test”来评估并按我的预期工作。这是实现:

var ngSwitchWhenDirective = ngDirective({
  transclude: 'element',
  priority: 800,
  require: '^ngSwitch',
  compile: function(element, attrs) {
    return function(scope, element, attr, ctrl, $transclude) {
      var expr = scope.$eval(attrs.ngSwitchWhen),
          ngSwitchWhen = expr !== undefined ? expr : attrs.ngSwitchWhen;
      ctrl.cases['!' + ngSwitchWhen] = (ctrl.cases['!' + ngSwitchWhen] || []);
      ctrl.cases['!' + ngSwitchWhen].push({ transclude: $transclude, element: element });
    };
  }
});

有人知道我做错了什么吗?任何帮助将不胜感激。

提前致谢!

更新

澄清一下,这是 Angular 团队如何测试 ng-switch 的示例。只是为了表明我正在以类似的方式进行测试,但没有得到预期的结果。

另外,我忘记将我的代码反转为 $rootScope,到目前为止,您所看到的是我试图让这项工作创建一个新范围以避免依赖 $rootScope 进行更改。

it('should switch on value change', inject(function($rootScope, $compile) {
    element = $compile(
      '<div ng-switch="select">' +
      '<div ng-switch-when="1">first:{{name}}</div>' +
      '<div ng-switch-when="2">second:{{name}}</div>' +
      '<div ng-switch-when="true">true:{{name}}</div>' +
      '</div>')($rootScope);
    expect(element.html()).toEqual(
       '<!-- ngSwitchWhen: 1 --><!-- ngSwitchWhen: 2 --><!-- ngSwitchWhen: true -->');
    $rootScope.select = 1;
    $rootScope.$apply();
    expect(element.text()).toEqual('first:');
    $rootScope.name="shyam";
    $rootScope.$apply();
    expect(element.text()).toEqual('first:shyam');
    $rootScope.select = 2;
    $rootScope.$apply();
    expect(element.text()).toEqual('second:shyam');
    $rootScope.name = 'misko';
    $rootScope.$apply();
    expect(element.text()).toEqual('second:misko');
    $rootScope.select = true;
    $rootScope.$apply();
    expect(element.text()).toEqual('true:misko');
}));

【问题讨论】:

  • 它在测试之外是否有效?测试运行时 element.text() 返回什么?
  • 是的,它确实适用于实际用例。当测试运行时, element.text() 是 '' (空字符串)。调试它我发现编译内部函数上的范围变量没有像我在真实用例中那样的“测试”属性。也许这与范围可见性有关。
  • 这可能会暴露我的无知,但你能确认你的测试目的吗?好像您已经发布了 ngSwitchWhen 的 AngularJS 源代码:您要测试吗?
  • 正如我所描述的,我想让 Angular 的 ng-switch-when 来解析表达式,在这个测试的情况下,让 ng-switch 值与数组值匹配。
  • 我的错,在改回 $rootScope 并在编译之前移动 $rootScope.test 之后,我能够解决问题,非常感谢@Jonathan。

标签: unit-testing angularjs angularjs-directive angularjs-scope ng-switch


【解决方案1】:

因此,在移动了一些代码之后,我发现在更改 $rootScope 以测试功能时不涉及的变量应该在编译要测试的元素之前定义。感谢@Jonathan 的提示。

这是带有附加测试用例的工作代码:

it('should evaluate expressions to match switch value', inject(function($rootScope, $compile) {
  $rootScope.array = ["leog", ".me"];
  $rootScope.obj = {"key": "value"};
  $rootScope.$apply();
  element = $compile(
    '<div ng-switch="select">' +
      '<div ng-switch-when="obj.key">obj.key:{{obj.key}}</div>' +
      '<div ng-switch-when="array[0]">array[0]:{{array[0]}}</div>' +
      '<div ng-switch-when="array[1]">array[1]:{{array[1]}}</div>' +
    '</div>')($rootScope);
  expect(element.html()).toEqual('<!-- ngSwitchWhen: obj.key -->' +
                                 '<!-- ngSwitchWhen: array[0] -->' +
                                 '<!-- ngSwitchWhen: array[1] -->');
  $rootScope.select = "value1";
  $rootScope.$apply();
  expect(element.text()).toEqual('obj.key:value');
  $rootScope.select = "leog";
  $rootScope.$apply();
  expect(element.text()).toEqual('array[0]:leog');
  $rootScope.select = ".me";
  $rootScope.$apply();
  expect(element.text()).toEqual('array[1]:.me');
}));

谢谢大家。

【讨论】:

    【解决方案2】:

    $scope.$apply 需要在要执行的括号内有一个函数,这是您的测试代码所缺少的。为了在测试时让事情发生,我使用 $scope.$digest() (而不是 $scope.$apply(); 这会启动一个手动摘要循环,否则该循环不会在测试中运行。

    【讨论】:

    • 已经测试了您的两种可能的解决方案,但什么也没有。无论如何谢谢@MBielski
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多