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

fea*_*ool 3 javascript mocha.js node.js sinon chai

tl;博士

你如何在 sinon 中“从头开始”创建一个 object.method() ?

上下文

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

我正在做单元测试,我测试Parser对象本身(它们在其他地方测试),但我需要一个响应#parse(). 我可以实例化并存根一个真正的解析器,但这会将不必要的代码拖入测试的这一部分。

问题

我很确定这很容易使用 sinon 的 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)
Run Code Online (Sandbox Code Playgroud)

Ste*_*mas 5

创建一个虚拟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();
Run Code Online (Sandbox Code Playgroud)