在sinon中创build一个假的object.method()从头开始?

TL;博士

如何在sinon中创build一个object.method()从头开始?

上下文

例如,我有一个Parser类的家庭,其中每个实现#parse(text)方法,并返回一个ParseTree对象或返回null

我正在进行unit testing,我没有testingParser对象(他们在别处testing过),但是我需要一个可testing的对象来响应#parse() 。 我可以实例化和存根真正的parsing器,但是拖拽不必要的代码到这部分testing中。

这个问题

我很确定,使用sinon的spy(),stub()和/或mock()api很容易,所以:我如何创build一个可testing的对象:

  • 响应parse()方法
  • validation它被调用一次
  • 返回一个我指定的任意对象?

我试过了

下面的例子在sinon.stub()的调用中失败了,因为sinon.spy()对象不能用parse方法存根sinon.spy() 。 (这个例子也应该validationfake_parser.parse()test_text调用了一次,但是没有):

 var test_text = 'any text' var fake_parse_tree = sinon.spy() var fake_parser = sinon.stub(sinon.spy(), 'parse').returns(fake_parse_tree) expect(fake_parser.parse(test_text)).to.equal(fake_parse_tree) 

创build一个虚拟Parser对象并存根它的parse()方法。 细节将取决于你如何创build你的parsing器,但是像这样:

 var Parser = { parse: function() { } }; var parseStub = sinon.stub(Parser, 'parse'); parseStub.returns(fake_parse_tree); // execute code that invokes the parser parseStub.callCount.should.equal(1); parseStub.alwaysCalledWithExactly(test_text).should.be.true(); 

@史蒂芬·托马斯在这里给出了正确的答案 。 为了将来的参考,这是我最终做的。 'aha'是sinon.stub(object, 'method')返回sinon.stub(object, 'method') 方法 ,而不是对象。

因为这是JavaScript(和方法是第一类对象)返回的方法是非常有道理的:

 var test_text = 'any text'; var parse_tree = sinon.spy(); // could be any object var proxy_parser = { parseText: function() { } }; var stubbed_method = sinon.stub(proxy_parser, 'parseText').returns(parse_tree) // App specific tests not shown here: // ...pass proxy_parser to a function that calls proxy_parser.parseText() // ...verify that the function returned the parse_tree expect(stubbed_method.callCount).to.equal(1) expect(stubbed_method.alwaysCalledWithExactly(test_text)).to.be.true