Stubs are used in writing tests which are an important part of development. A stub replaces the whole function being tested.
They are helpful in scenarios such as:
- External calls which make tests slow and difficult to write (e.g. HTTP calls/DB calls)
- Triggering different outcomes for a piece of code (e.g. simulating errors vs. success responses)
Example Function:
const request = require('request');
const getPhotosByAlbumId = (id) => {
const requestUrl = `https://jsonplaceholder.typicode.com/albums/${id}/photos?_limit=3`;
return new Promise((resolve, reject) => {
request.get(requestUrl, (err, res, body) => {
if (err) {
return reject(err);
}
resolve(JSON.parse(body));
});
});
};
module.exports = getPhotosByAlbumId;
Example Test with Stub:
const expect = require('chai').expect;
const request = require('request');
const sinon = require('sinon');
const getPhotosByAlbumId = require('./index');
describe('with Stub: getPhotosByAlbumId', () => {
before(() => {
sinon.stub(request, 'get')
.yields(null, null, JSON.stringify([
{ albumId: 1, id: 1, title: "A real photo 1", url: "https://via.placeholder.com/600/92c952", thumbnailUrl: "https://via.placeholder.com/150/92c952" },
{ albumId: 1, id: 2, title: "A real photo 2", url: "https://via.placeholder.com/600/771796", thumbnailUrl: "https://via.placeholder.com/150/771796" },
{ albumId: 1, id: 3, title: "A real photo 3", url: "https://via.placeholder.com/600/24f355", thumbnailUrl: "https://via.placeholder.com/150/24f355" }
]));
});
after(() => {
request.get.restore();
});
it('should getPhotosByAlbumId', (done) => {
getPhotosByAlbumId(1).then((photos) => {
expect(photos.length).to.equal(3);
photos.forEach(photo => {
expect(photo).to.have.property('id');
expect(photo).to.have.property('title');
expect(photo).to.have.property('url');
});
done();
});
});
});