The problem here is that $()
is a function that returns an object with the method val()
. So you have to stub $() to return a stubbed object having the method val.
$ = sinon.stub();
$.withArgs('#category').returns(sinon.stub({val: function(){}}));
But the main mistake here is to let the code you want to test call the function $() to create new instances. Why? Its best practice to create no new instances in your class, but to pass them into the constructor. Let's say you have function that will get a value out of an input, double it, and write it back to another:
function doubleIt(){
$('#el2').val(('#el1').val() *2);
}
In this case you create 2 new objects by calling $()
. Now you have to stub $()
to return a mock and a stub. Using the next example you can avoid this:
function doubleIt(el1, el2){
el2.val(el1.val() *2);
}
While, in the first case you have to stub $ to return a stub, in the second case you can easily pass a stub and a spy into your function.
So the sinon test for the second one would look like this:
var el1 = sinon.stub({val: function(){}});
el1.returns(2);
var el2 = sinon.spy({val: function(){}}, 'val')
doubleIt(el1, el2)
assert(el2.withArgs(4).calledOnce)
So, as you have no dom elements here, you can simply test your application logic with no need to create the same dom as in your app.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…