Jasmine 模拟链式方法与 Karma 和 Angular [英] Jasmine mock chained methods with Karma and Angular

查看:22
本文介绍了Jasmine 模拟链式方法与 Karma 和 Angular的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想模拟 angular.element.而且我想确保 angular.element 已被调用一定次数,并且 anguler.element.attr 也已被调用.

I want to mock angular.element. And I want to ensure angular.element has been called a certain amount of times and that anguler.element.attr has been called too.

我有以下代码:

var things = $scope.getThings();

for (var i = 0; i < things.length; i++) {
  if (things[i].type == "xyz") {
    angular.element("#thing-" + things[i].id)
      .attr("foo", things[i].bar);
  };
};

在我的测试中,我有:

var things = [
  {
    id: 1,
    type: "xyz",
    bar: 10
  },
  {
    id: 2,
    type: "abc",
    bar: 33
  }
];

spyOn($rootScope, "getThings").and.returnValue(things);
spyOn(angular, "element").and.returnValue();

$rootScope.doThings(); // call controller method

expect(angular.element.calls.count()).toBe(1);

但它给出了以下错误:

TypeError: undefined 不是一个对象(正在评估'angular.element("#thing-" + things[i].id).attr')

TypeError: undefined is not an object (evaluating 'angular.element("#thing-" + things[i].id).attr')

我还希望我的测试具有以下内容:

I also want my test to have something like:

expect(angular.element.attr.calls.count()).toBe(1);
expect(angular.element.attr).tohaveBeenCalledWith("foo", things[0].bar);

推荐答案

应该监视或模拟链接方法的方式完全取决于它们在被监视对象上的定义方式.

The way chained methods should be spied or mocked solely depends on how they are defined on the spied objects.

在 Angular jqLit​​e 的情况下,或者在你的情况下,jQuery(两者都通过 angular.element 门面透明地提供)链式方法定义在构造函数原型上,它在工厂函数中公开为 angular.element.prototypejQuery.prototype (angular.element === jQuery 当 jQuery 加载时).

In the case of Angular jqLite, or in your case, jQuery (both are transparently served through angular.element facade) chained methods are defined on constructor prototype, which is exposed on factory function as angular.element.prototype or jQuery.prototype (angular.element === jQuery when jQuery is loaded).

为了同时监视 angular.elementangular.element(...).attr 应该是:

In order to spy on both angular.element and angular.element(...).attr it should be:

spyOn(angular, 'element').and.callThrough();
spyOn(angular.element.prototype, 'attr').and.callThrough();
...
expect(angular.element).toHaveBeenCalled();
expect(angular.element.prototype.attr).toHaveBeenCalled();

callThrough 在这种情况下很重要,否则整个链都应该手动存根.

callThrough is important in this case because otherwise the whole chain should be stubbed manually.

这篇关于Jasmine 模拟链式方法与 Karma 和 Angular的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆