Jasmine - 如何spyOn实例方法

sfl*_*che 22 javascript jasmine

我有一个功能

var data = {};
var myFunc = function() {
  data.stuff = new ClassName().doA().doB().doC();
};
Run Code Online (Sandbox Code Playgroud)

我想测试doA,doBdoC全部调用.

我试图监视像这样的实例方法

beforeEach(function() {
  spyOn(ClassName, 'doA');
};
it('should call doA', function() {
  myFunc();
  expect(ClassName.doA).toHaveBeenCalled();
});
Run Code Online (Sandbox Code Playgroud)

但那只是给了我一个"doA()方法不存在"的错误.

有任何想法吗?

小智 40

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

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

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

当然,这是假设doA生活在原型链中.如果它是一个自己的属性,那么没有能够在不能引用匿名对象的情况下使用的技术myFunc.如果您可以访问ClassName内部的实例myFunc,那将是理想的,因为您可以直接使用spyOn该对象.

PS你应该把"茉莉花"放在标题中.


Krz*_*ski 7

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

依赖注入意味着为对象提供自己的实例变量.真.而已.

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

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

一些测试的时间

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();
  });
});
Run Code Online (Sandbox Code Playgroud)
<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>
Run Code Online (Sandbox Code Playgroud)