测试AngularJS作用域变量

5

我正在尝试实现一个依赖于作用域变量的测试。我想让ng-switch-when解析表达式。这是我正在尝试做的事情(更新使用$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()**为空字符串。调试时我发现,在编译内部函数的作用域变量中,没有像实际用例中一样具有“test”属性。也许这与作用域可见性有关。 - leog
正如我所描述的,我希望使用Angular中的ng-switch-when来解析表达式,在这个测试中,让ng-switch的值匹配一个数组值。 - leog
是因为你在测试定义之前编译了HTML吗?因此,test[0]也将未定义。 - Jonathan
如果将$scope.test=...移动到element = $compile...上面一行,它还能正常工作吗? - Jonathan
1
我的不好,改回$rootScope并将$rootScope.test移动到编译之前,我成功解决了这个问题,非常感谢@Jonathan。 - leog
显示剩余3条评论
2个回答

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');
}));

谢谢你们所有人。

0

$scope.$apply需要在括号内包含一个要执行的函数,而您的测试代码缺少此功能。为了在测试时使事情发生,我使用$scope.$digest()(而不是$scope.$apply()); 这会启动一个手动的脏检查循环,在测试中本来不会运行。


已经尝试了你提供的两种可能的解决方案,但都没有效果。无论如何感谢@MBielski。 - leog

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接