What is a stub in Node.js ?
A small program routine that substitutes for a longer program which is possible to be loaded later or that is remotely located.
Features of stub:
- Stubs can be either anonymous.
- Stubs can be wrapped into existing functions. When we wrap a stub into the existing function the original function is not called.
- Stubs are functions or programs that affect the behavior of components or modules.
- Stubs are dummy objects for testing.
- Stubs implement a pre-programmed response.
Example:
var fs = require( 'fs' ) var writeFileStub = sinon.stub(fs, 'writeFile' , function (path, data, cb) { return cb( null ) }) expect(writeFileStub).to.be.called writeFileStub.restore() |
When to use stubs?
- Prevent a specific method from being called directly.
- Controlling method behavior down a specific path from a test to force the code. For example: Error handling.
- Replacing the problematic pieces of code.
- Testing asynchronous code easy.
Example To Create Asynchronous Stub That Throws An Exception:
require( "@fatso83/mini-mocha" ).install(); const sinon = require( "sinon" ); const PubSub = require( "pubsub-js" ); const referee = require( "@sinonjs/referee" ); const assert = referee.assert; describe( "PubSub" , function () { it( "Calling all the subscribers, irrespective of exceptions." , function () { const message = "an example message" ; const stub = sinon.stub().throws(); const spy1 = sinon.spy(); const spy2 = sinon.spy(); const clock = sinon.useFakeTimers(); PubSub.subscribe(message, stub); PubSub.subscribe(message, spy1); PubSub.subscribe(message, spy2); assert.exception(()=>{ PubSub.publishSync(message, "some data" ); clock.tick(1); }); assert.exception(stub); assert(spy1.called); assert(spy2.called); assert(stub.calledBefore(spy1)); clock.restore(); }); }); |
Output:
Calling all the subscribers, irrespective of exceptions.
Example Of Stubs: Let us consider an example of an e-commerce website for purchasing items. If we are successful a mail will be sent to the customer.
const purchaseItems(cartItems, user)=>{ let payStatus = user.paymentMethod(cartItems) if (payStatus === "successful" ) { user.SuccessMail() } else { user.redirect( "error_page_of_payment" ) } } } function () { // Mail will be send for successful payment. let paymentStub = sinon.stub().returns( "successful" ) let mailStub = sinon.stub( let user = { paymentMethod: paymentStub, SuccessMail: mailStub } purchaseItems([], user) assert(mailStub.called) } |
Example 1: A Simple Example To Execute Stubs.
<!DOCTYPE html> < html > < head > < title >Page Title</ title > </ head > < body > < div id = "mocha" ></ div > </ body > </ html > |
<!DOCTYPE html> < html > < head > < script > mocha.setup('bdd'); function saveUser(user, callback) { $.post('/users', { first: user.firstname, last: user.lastname }, callback); } describe('saveUser', function () { it('should call callback after saving', function () { // We'll stub $.post so a // request is not sent var post = sinon.stub($, 'post'); post.yields(); // We can use a spy as the callback // so it's easy to verify var callback = sinon.spy(); saveUser({ firstname: 'Han', lastname: 'Solo' }, callback); post.restore(); sinon.assert.calledOnce(callback); }); }); mocha.run(); </ script > </ head > </ html > |
Output:
Example 2:
<!DOCTYPE html> < html > < head > < title >Page Title</ title > </ head > < body > < h1 >w3wiki</ h1 > < div id = "mocha" ></ div > </ body > </ html > |
<!DOCTYPE html> < html > < head > < script > mocha.setup('bdd'); function saveUser(user, callback) { $.post('/users', { first: user.firstname, last: user.lastname }, callback); } describe('saveUser', function () { it( 'It will send the correct parameters to the expected URL', function () { // We'll stub $.post same as before var post = sinon.stub($, 'post'); // We'll set up some variables to // contain the expected results var expectedUrl = '/users'; var expectedParams = { first: 'Expected first name', last: 'Expected last name' }; // We can also set up the user we'll // save based on the expected data var user = { firstname: expectedParams.first, lastname: expectedParams.last } saveUser(user, function () { }); post.restore(); sinon.assert.calledWith(post, expectedUrl, expectedParams); }); }); mocha.run(); </ script > </ head > </ html > |
Output:
Contact Us