在 sinon 中创建一个假的 object.method() "from scratch"?
Creating a fake object.method() "from scratch" in sinon?
tl;博士
如何在 sinon 中创建 object.method() "from scratch"?
上下文
例如,我有一个 Parser
类 家族,其中每个家族都实现了一个 #parse(text)
方法和 returns 一个 ParseTree
对象或 returns null
。
我正在做单元测试,我 不是 测试 Parser
对象本身(它们在别处测试)但我需要一个响应 #parse()
。我可以实例化并存根一个真正的解析器,但这会将不必要的代码拖到这部分测试中。
问题
我很确定这很容易使用 sinon 的 spy()、stub() and/or mock() api,所以:我如何创建一个可测试的对象:
- 响应 parse() 方法
- 验证调用一次
- returns我指定的任意对象?
我试过的
以下设计的示例在调用 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')
returns 存根的 方法 ,而不是对象。
因为这是 javascript(方法是 first-class 对象)返回方法非常有意义:
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
tl;博士
如何在 sinon 中创建 object.method() "from scratch"?
上下文
例如,我有一个 Parser
类 家族,其中每个家族都实现了一个 #parse(text)
方法和 returns 一个 ParseTree
对象或 returns null
。
我正在做单元测试,我 不是 测试 Parser
对象本身(它们在别处测试)但我需要一个响应 #parse()
。我可以实例化并存根一个真正的解析器,但这会将不必要的代码拖到这部分测试中。
问题
我很确定这很容易使用 sinon 的 spy()、stub() and/or mock() api,所以:我如何创建一个可测试的对象:
- 响应 parse() 方法
- 验证调用一次
- returns我指定的任意对象?
我试过的
以下设计的示例在调用 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 sinon.stub(object, 'method')
returns 存根的 方法 ,而不是对象。
因为这是 javascript(方法是 first-class 对象)返回方法非常有意义:
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