sinon stub by example
Mar 18, 2014 00:00 · 598 words · 3 minute read
What is Stub ?
“stubs replace the real object with a test specific object that feed the desire indirect inputs into the system under test”. (xUnit test pattern)
stubs function has pre-programmed behaviour. they support all the spies functionalities as well.
When to use Stub?
stubs do not proxy the original method , they have an API for controlling the behaviour .
Use stubs when you want to
- control the method behaviour, for instance force a method to throwing an exception to check the error handling functionalities.
- prevent a method to get call directly to stop triggering undesired behaviour (sinon stub documentaion).
Production Code
below is the production code that suppose to give us some simple functionalities.
production codeJavaScript
var sinonStub = {
callMyMethod: function (number, arg1, arg2) {
var someValue = '';
for (var i = 0; i < number; i++) {
someValue = this.myMethod(arg1, arg2);
}
return someValue;
},
myMethod: function (arg1, arg2) {
try {
this.exceptionMethod();
}
catch (exception) {
}
return 'test'
},
myMethodWithCallBack: function () {
var status;
this.methodWithCallBack({
onSuccess: function (arg1, arg2) {
status = 'success' + arg1 + arg2;
},
onError: function () {
status = 'failure'
}
});
return status;
},
methodWithCallBack: function (callback) {
return true;
},
exceptionMethod: function () {
return 'some value';
}
};
Test Cases
below are the different test cases that tries to test our production code functionalities.
Test if a method get called
Similar to the sinon spies you can test a method get called or not .
get calledJavaScript
SinonStubTest.prototype.testCallMyMethodShouldCallMyMethodOneTime = function () {
expectAsserts(1);
var myMethodStub = this._sandbox.stub(sinonStub, 'myMethod');
sinonStub.callMyMethod(1);
assertTrue(myMethodStub.calledOnce);
};
Test if a method get called with expected args
it test a method get called with expected args or not.
get called with argsJavaScript
SinonStubTest.prototype.testMyMethodShouldReturnExpectedValueOnNthCall = function () {
expectAsserts(3);
var myMethodStub = this._sandbox.stub(sinonStub, 'myMethod');
var arg1 = 'arg one';
var arg2 = 'arg two';
var firstCall = 'first call';
var secondCall = 'second call';
var thirdCall = 'third call';
myMethodStub.onCall(0).returns(firstCall); //onFirstCall
myMethodStub.onCall(1).returns(secondCall); //onSecondCall
myMethodStub.onCall(2).returns(thirdCall); //onThirdCall
var actualValue = sinonStub.callMyMethod(1, arg1, arg2);
assertEquals(firstCall, actualValue);
actualValue = sinonStub.callMyMethod(1, arg1, arg2);
assertEquals(secondCall, actualValue);
actualValue = sinonStub.callMyMethod(1, arg1, arg2);
assertEquals(thirdCall, actualValue);
};
Always return some value
in same way you can force the “myMethod” to always return some expected value.
always return valueJavaScript
SinonStubTest.prototype.testMyMethodShouldAlwaysReturnExpectedValue = function () {
expectAsserts(1);
var myMethodStub = this._sandbox.stub(sinonStub, 'myMethod');
var expectedValue = "some expected value";
myMethodStub.returns(expectedValue);
var actualValue = sinonStub.callMyMethod(3);
assertEquals(expectedValue, actualValue);
};
Ask stubbed method to raise an exception
“throws” will throw your expected error which could be string or object. it can help you test your error handling scenarios.
raise exception
SinonStubTest.prototype.testExceptionMethodRaiseException = function () {
expectAsserts(2);
var exceptionMethodStub = this._sandbox.stub(sinonStub, 'exceptionMethod');
var error = {someKey: "TypeError"};
exceptionMethodStub.throws(error);
var actualValue = sinonStub.callMyMethod(1);
assertTrue(exceptionMethodStub.threw());
assertTrue(exceptionMethodStub.threw(error));
};
Asked stubbed method to returns expected callback “yieldsTo” will help you test the callbacks and force your code to call your expected callbacks.
in below code it force the “methodWithCallBack” function to call the onError callback.
yields to callback
yields to callbackJavaScript
SinonStubTest.prototype.testOnFailureOfMyMethodWithCallBackShouldReturnExpectedValue = function () {
expectAsserts(1);
var myMethodStub = this._sandbox.stub(sinonStub, 'methodWithCallBack');
var expectedValue = "failure";
myMethodStub.yieldsTo("onError");
var actualValue = sinonStub.myMethodWithCallBack();
assertEquals(expectedValue, actualValue);
};
yields to callback with args
similar to the above example you can also specify your callback args as well.
yields to callback with argsJavaScript
SinonStubTest.prototype.testOnFailureOfMyMethodWithCallBackShouldReturnExpectedValueWithArgs = function () {
expectAsserts(1);
var myMethodStub = this._sandbox.stub(sinonStub, 'methodWithCallBack');
var expectedValue = "success"+'first'+ 'second';
myMethodStub.yieldsTo("onSuccess",'first','second','third');
var actualValue = sinonStub.myMethodWithCallBack();
assertEquals(expectedValue, actualValue);
};
Download
you can find the full API reference on sinon spy documentation . Also feel free to download the full source code of this example from my github.