如何在sinon中“从头开始”创建object.method()?
例如,我有一个Parser
类系列,每个类实现一个#parse(text)
方法并返回一个ParseTree
对象或返回null
。
我正在进行单元测试,我不测试Parser
个对象本身(它们在别处测试)但我需要一个响应#parse()
的可测试对象。我可以实例化并存根一个真正的Parser,但这会将不必要的代码拖入测试的这一部分。
我很确定使用sinon的spy(),stub()和/或mock()api很容易,所以:我如何创建一个可测试的对象:
以下设计示例在调用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)
,但它没有调用:
(function($){
function floatLabel(inputType){
$(inputType).each(function(){
var $this = $(this);
var text_value = $(this).val();
// on focus add class "active" to label
$this.focus(function(){
$this.next().addClass("active");
});
// on blur check field and remove class if needed
$this.blur(function(){
if($this.val() === '' || $this.val() === 'blank'){
$this.next().removeClass();
}
});
// Check input values on postback and add class "active" if value exists
if(text_value!==''){
$this.next().addClass("active");
}
});
// Automatically remove floatLabel class from select input on load
//$( "select" ).next().removeClass();
}
// Add a class of "floatLabel" to the input field
floatLabel(".floatLabel");
});
答案 0 :(得分:4)
创建一个虚拟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();
方法。详细信息将取决于您创建解析器的方式,但类似于:
Set body = New NotesRichTextItem(maildoc,"Body")
Call body.AppendDocLink(doc, "Click me")
答案 1 :(得分:2)
@Stephen Thomas gave the right answer here。为了将来参考,这是我最终做的。 '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