Javascript Jasmine - 如何监视实例方法

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/31364930/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-23 06:36:21  来源:igfitidea点击:

Jasmine - how to spyOn instance methods

javascriptjasmine

提问by sfletche

I have a function

我有一个功能

var data = {};
var myFunc = function() {
  data.stuff = new ClassName().doA().doB().doC();
};

I'd like to test that doA, doB, and doCwere all called.

我想测试一下doA, doB, 并且doC都被调用了。

I tried spying on the instance methods like this

我尝试监视这样的实例方法

beforeEach(function() {
  spyOn(ClassName, 'doA');
};
it('should call doA', function() {
  myFunc();
  expect(ClassName.doA).toHaveBeenCalled();
});

but that just gives me a "doA() method does not exist" error.

但这只是给了我一个“doA() 方法不存在”的错误。

Any ideas?

有任何想法吗?

回答by mooiamaduck

Where you went wrong was your understanding of how to refer to methods in JavaScript in a static context. What your code is actually doing is spying on ClassName.doA(that is, the function attached to the ClassNameconstructor as the property doA, which is not what you want).

你出错的地方在于你对如何在静态上下文中引用 JavaScript 中的方法的理解。您的代码实际上在做的是监视ClassName.doA(即,ClassName作为 property附加到构造函数的函数doA,这不是您想要的)。

If you want to detect when that method gets called on any instance of ClassNameanywhere, you need to spy on the prototype.

如果您想检测该方法何时在任何ClassName地方的任何实例上被调用,您需要监视原型。

beforeEach(function() {
  spyOn(ClassName.prototype, 'doA');
});
it('should call doA', function() {
  myFunc();
  expect(ClassName.prototype.doA).toHaveBeenCalled();
});

Of course, this is assuming that doAlives in the prototype chain. If it's an own-property, then there is no technique that you can use without being able to refer to the anonymous object in myFunc. If you had access to the ClassNameinstance inside myFunc, that would be ideal, since you could just spyOnthat object directly.

当然,这是假设doA存在于原型链中。如果它是一个自有财产,那么如果不能在myFunc. 如果您可以访问ClassName内部的实例myFunc,那将是理想的,因为您可以直接访问spyOn该对象。

P.S. You should really put "Jasmine" in the title.

PS 你真的应该把“茉莉花”放在标题中。

回答by Krzysztof Safjanowski

Let's do some code refactoring as we want implement constructor injection patternas James Shore mentions that:

让我们进行一些代码重构,因为我们想要实现构造函数注入模式,正如 James Shore 提到的:

Dependency injection means giving an object its own instance variables. Really. That's it.

依赖注入意味着给一个对象自己的实例变量。真的。就是这样。

var data = {};
var stuff = new ClassName()

var myFunc = function(stuff) { // move step of creation new object outside
  data.stuff = stuff.doA().doB().doC();
};

And time for some tests

和一些测试的时间

function ClassName() {
}

var data = {};
var stuff = new ClassName()

var myFunc = function(stuff) {
  data.stuff = stuff.doA().doB().doC();
};


describe('stub for ClassName implementation', function() {
  var stubStuff = {
    doA: function() {
      return stubStuff
    },
    doB: function() {
      return stubStuff
    },
    doC: function() {
      return stubStuff
    }
  }

  beforeEach(function() {
    spyOn(stubStuff, 'doA').and.callThrough();
  });

  it('calls "doA" on "myFunc" exection', function() {
    myFunc(stubStuff);
    expect(stubStuff.doA).toHaveBeenCalled();
  });
});
<link href="//safjanowski.github.io/jasmine-jsfiddle-pack/pack/jasmine.css" rel="stylesheet" />
<script src="//safjanowski.github.io/jasmine-jsfiddle-pack/pack/jasmine-2.0.3-concated.js"></script>