Javascript 创建假对象。方法();“从头开始”;在西农? tl;博士

Javascript 创建假对象。方法();“从头开始”;在西农? tl;博士,javascript,node.js,mocha.js,sinon,chai,Javascript,Node.js,Mocha.js,Sinon,Chai,如何在sinon中“从头开始”创建object.method() 上下文 例如,我有一系列Parser类,其中每个类实现一个#parse(text)方法,并返回一个ParseTree对象或返回null 我在做单元测试,我没有测试解析器对象本身(它们在别处测试),但我需要一个响应#parse()的可测试对象。我可以实例化并存根一个真正的解析器,但这会将不必要的代码拖到测试的这一部分 问题 我敢肯定,使用sinon的spy()、stub()和/或mock()api很容易做到这一点,所以:如何创建一个

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

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

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

问题 我敢肯定,使用sinon的spy()、stub()和/或mock()api很容易做到这一点,所以:如何创建一个可测试的对象:

  • 响应parse()方法
  • 验证是否调用过一次
  • 返回我指定的任意对象
我试过的 以下人为示例在调用
sinon.stub()
时失败,因为无法使用
parse
方法存根
sinon.spy()
对象。(此示例还应验证是否使用
test\u text
调用了一次
fake\u parser.parse()
,但没有):


创建一个虚拟
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();
@斯蒂芬·托马斯。作为将来的参考,以下是我最后做的。“aha”是指
sinon.stub(object,'method')
返回stubbed方法,而不是对象

因为这是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

啊!!一个关键点是
sinon.stub(obj,method)
返回stubbed方法,而不是对象。我感到困惑,因为我试图将parseStub传递给我的代码,而我的代码需要一个解析器。谢谢
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