在 sinon 中创建假 object.method() "from scratch"?



tl; dr

如何在Sinon中创建一个object.Method()"从头开始"?

上下文

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

我正在进行单元测试,而我不是Parser对象本身进行测试(它们在其他地方进行了测试),但是我需要一个可响应#parse()的可测试对象。我可以实例化和固态真正的解析器,但是将不必要的代码拖入了测试的这一部分。

问题

我很确定使用Sinon's Spy(),stub()和/或Mock()API很容易,因此:如何创建一个可测试的对象:

  • 响应parse()方法
  • 验证它被称为一次
  • 返回我指定的任意对象?

我尝试过的

sinon.stub()的调用中,以下人为的示例失败了,因为sinon.spy()对象不能用parse方法固定。(此示例还应验证fake_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)

创建一个虚拟Parser对象,并存根它的parse()方法。细节将取决于您如何创建解析器,但类似于:

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();

@stephen Thomas在这里给出了正确的答案。供将来参考,这是我最终所做的。" aha"是 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

最新更新