Sinon Stub unit test - javascript

I have written a small piece of code to understand the sinon functionality.
Below is the piece of code to check:
toBeTested.js:
const getAuthenticationInfo = orgId => {
return 'TEST';
};
const getAuthToken = orgId => {
var lmsInfo = getAuthenticationInfo(orgId);
return lmsInfo;
};
module.exports = {
getAuthenticationInfo,
getAuthToken
};
api-test.js:
const sinon = require('sinon');
const toBeTested = require('./toBeTested');
sinon.stub(toBeTested, 'getAuthenticationInfo').returns('mocked-response');
console.log(toBeTested.getAuthInfo());
I am expecting console.log output as mocked-response. But it is giving response as TEST.

Here is the unit test solution:
index.js:
const getAuthenticationInfo = orgId => {
return 'TEST';
};
const getAuthToken = orgId => {
var lmsInfo = exports.getAuthenticationInfo(orgId);
return lmsInfo;
};
exports.getAuthenticationInfo = getAuthenticationInfo;
exports.getAuthToken = getAuthToken;
index.spec.js:
const mod = require('./');
const sinon = require('sinon');
const { expect } = require('chai');
describe('53605161', () => {
it('should stub getAuthenticationInfo correctly', () => {
const stub = sinon.stub(mod, 'getAuthenticationInfo').returns('mocked-response');
const actual = mod.getAuthToken(1);
expect(actual).to.be.equal('mocked-response');
expect(stub.calledWith(1)).to.be.true;
stub.restore();
});
it('getAuthenticationInfo', () => {
const actual = mod.getAuthenticationInfo();
expect(actual).to.be.equal('TEST');
});
});
Unit test result with 100% coverage report:
53605161
✓ should stub getAuthenticationInfo correctly
✓ getAuthenticationInfo
2 passing (7ms)
---------------|----------|----------|----------|----------|-------------------|
File | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s |
---------------|----------|----------|----------|----------|-------------------|
All files | 100 | 100 | 100 | 100 | |
index.js | 100 | 100 | 100 | 100 | |
index.spec.js | 100 | 100 | 100 | 100 | |
---------------|----------|----------|----------|----------|-------------------|
Source code: https://github.com/mrdulin/mocha-chai-sinon-codelab/tree/master/src/stackoverflow/53605161

Related

nodejs Jest testing exec.stdout.on('data',data)

Trying to to test a function the incorporates the exec of child_process library.
const { exec } = require('child_process')
const randomFunc = () => {
const newSync = exec('some command to execute')
newSync.stdout.on('data', data => {
console.log(data.toString())
})
}
testfile:
const {randomFunc} = require(randomFuncFile)
const { exec } = require('child_process')
jest.mock('child_process')
it('test', () => {
const readStreamObject = {
on: jest.fn().mockImplementation(function (event, handler) {
handler('streaming ')
})
}
exec.mockImplementation(data => ({stdout: readStreamObject})
randomFunc()
expect(exec.stdout.on).toHaveBeenCalled()
}
I'm getting
TypeError: Cannot read properties of undefined (reading 'on')
some tips would be great.
You can get the mock stdout returned by mocked exec() function via exec.mock.results[0].value.stdout, See mockFn.mock.results
index.js:
const { exec } = require('child_process');
const randomFunc = () => {
const newSync = exec('some command to execute');
newSync.stdout.on('data', (data) => {
console.log(data.toString());
});
};
module.exports = { randomFunc };
index.test.js:
const { exec } = require('child_process');
const { randomFunc } = require('./');
jest.mock('child_process');
it('test', () => {
const mStdout = {
on: jest.fn().mockImplementation(function (event, handler) {
handler('streaming');
}),
};
exec.mockImplementation(() => ({ stdout: mStdout }));
randomFunc();
// expect(mStdout.on).toHaveBeenCalled();
// or
expect(exec.mock.results[0].value.stdout.on).toHaveBeenCalled();
});
Test result:
PASS stackoverflow/75036469/index.test.js (8.403 s)
✓ test (15 ms)
console.log
streaming
at stackoverflow/75036469/index.js:6:13
----------|---------|----------|---------|---------|-------------------
File | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s
----------|---------|----------|---------|---------|-------------------
All files | 100 | 100 | 100 | 100 |
index.js | 100 | 100 | 100 | 100 |
----------|---------|----------|---------|---------|-------------------
Test Suites: 1 passed, 1 total
Tests: 1 passed, 1 total
Snapshots: 0 total
Time: 9.016 s

Stub chained promises with sinon

let image = await object
.firstCall(params)
.promise()
.then(data => {
return data
})
.catch(err => {
console.(err)
});
What's the way to stub the chained promises with sinon ? I've tried the following, but with no luck
promiseStub = sinon.stub().callsArg(0).resolves("something");
firtCallStub = sinon.stub(object, "firstCall").returns(this.promiseStub);
Unit test solution:
index.ts:
import { object } from './obj';
export async function main() {
const params = {};
return object
.firstCall(params)
.promise()
.then((data) => {
return data;
})
.catch((err) => {
console.log(err);
});
}
obj.ts:
export const object = {
firstCall(params) {
return this;
},
async promise() {
return 'real data';
},
};
index.test.ts:
import { main } from './';
import { object } from './obj';
import sinon from 'sinon';
import { expect } from 'chai';
describe('64795845', () => {
afterEach(() => {
sinon.restore();
});
it('should return data', async () => {
const promiseStub = sinon.stub(object, 'promise').resolves('fake data');
const firtCallStub = sinon.stub(object, 'firstCall').returnsThis();
const actual = await main();
expect(actual).to.be.equal('fake data');
sinon.assert.calledWithExactly(firtCallStub, {});
sinon.assert.calledOnce(promiseStub);
});
});
unit test result:
64795845
✓ should return data
1 passing (32ms)
----------|---------|----------|---------|---------|-------------------
File | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s
----------|---------|----------|---------|---------|-------------------
All files | 66.67 | 100 | 40 | 66.67 |
index.ts | 83.33 | 100 | 66.67 | 83.33 | 12
obj.ts | 33.33 | 100 | 0 | 33.33 | 3-6
----------|---------|----------|---------|---------|-------------------

Jest: Mock class method in a function

So just trying to understand how I mock a class function within a function itself. How do I mock the data returned from the exchange.someFunction() method so I can test the actual getPositions() function itself?
const library = require('library');
const exchange = new library.exchange_name();
async function getPositions() {
let positions = [];
const results = await exchange.someFunction();
// Do some stuff
return results;
}
I was trying to do the following but have no idea if I'm doing anything correct at all
const exchange = require('../../exchange');
jest.mock('library')
it('get balances', async () => {
library.someFunction.mockResolvedValue({
data: [{some data here}]
)}
}
Error thrown:
TypeError: Cannot read property 'mockResolvedValue' of undefined
Here is the unit test solution:
index.js:
const library = require('./library');
const exchange = new library.exchange_name();
async function getPositions() {
let positions = [];
const results = await exchange.someFunction();
return results;
}
module.exports = getPositions;
library.js:
function exchange_name() {
async function someFunction() {
return 'real data';
}
return {
someFunction,
};
}
module.exports = { exchange_name };
index.test.js:
const getPositions = require('./');
const mockLibrary = require('./library');
jest.mock('./library', () => {
const mockExchange = { someFunction: jest.fn() };
return { exchange_name: jest.fn(() => mockExchange) };
});
describe('61649788', () => {
it('get balances', async () => {
const mockExchange = new mockLibrary.exchange_name();
mockExchange.someFunction.mockResolvedValueOnce({ data: ['mocked data'] });
const actual = await getPositions();
expect(actual).toEqual({ data: ['mocked data'] });
expect(mockExchange.someFunction).toBeCalled();
});
});
unit test results with 100% coverage:
PASS stackoverflow/61649788/index.test.js (8.775s)
61649788
✓ get balances (7ms)
----------|---------|----------|---------|---------|-------------------
File | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s
----------|---------|----------|---------|---------|-------------------
All files | 100 | 100 | 100 | 100 |
index.js | 100 | 100 | 100 | 100 |
----------|---------|----------|---------|---------|-------------------
Test Suites: 1 passed, 1 total
Tests: 1 passed, 1 total
Snapshots: 0 total
Time: 10.099s

How to mock object creation and its method

new UrlBuilder(urlString).buildURL(params).getShortenedURL().then(data => {
.....
});
How can I stub the object creation and check whether getShortenedURL() has been called?
I tried
this.urlBuilder = sinon.stub(UrlBuilder.prototype, getShortenedURL).resolves({url: '/someUrl'});
But every time I run a test that has:
assert(this.urlBuilder.getShortenedURL.called);
it'll say
ReferenceError: getShortenedURL is not defined
Here is the unit test solution:
index.js:
const UrlBuilder = require('./urlBuilder');
function main() {
const urlString = 'https://stackoverflow.com/';
const params = {};
return new UrlBuilder(urlString)
.buildURL(params)
.getShortenedURL()
.then((data) => data);
}
module.exports = main;
urlBuilder.js:
class UrlBuilder {
constructor(url) {
this.url = url;
}
buildURL(params) {
return this;
}
getShortenedURL() {
return Promise.resolve('real data');
}
}
module.exports = UrlBuilder;
index.test.js:
const sinon = require('sinon');
const proxyquire = require('proxyquire');
const { expect } = require('chai');
describe('60214679', () => {
it('should pass', async () => {
const urlBuilderInstanceStub = {
buildURL: sinon.stub().returnsThis(),
getShortenedURL: sinon.stub().resolves('fake data'),
};
const urlBuilderStub = sinon.stub().callsFake(() => urlBuilderInstanceStub);
const main = proxyquire('./', {
'./urlBuilder': urlBuilderStub,
});
const actual = await main();
expect(actual).to.be.eq('fake data');
sinon.assert.calledWithExactly(urlBuilderStub, 'https://stackoverflow.com/');
sinon.assert.calledWithExactly(urlBuilderInstanceStub.buildURL, {});
sinon.assert.calledOnce(urlBuilderInstanceStub.getShortenedURL);
});
});
Unit test results with coverage report:
60214679
✓ should pass (2010ms)
1 passing (2s)
---------------|---------|----------|---------|---------|-------------------
File | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s
---------------|---------|----------|---------|---------|-------------------
All files | 70 | 100 | 40 | 70 |
index.js | 100 | 100 | 100 | 100 |
urlBuilder.js | 25 | 100 | 0 | 25 | 3,6,9
---------------|---------|----------|---------|---------|-------------------
Source code: https://github.com/mrdulin/expressjs-research/tree/master/src/stackoverflow/60214679

How to test `catch` and `then` with sinon js?

I have been trying to stub and mock my function to be able to test my function
SetExample.createCandyBox = function(config) {
this.getCandies(config.candyUrl)
.catch(() => {
return {};
})
.then((candies) => {
Advertisements.pushCandyBox(config, candies);
});
};
I want to test a scenario when the config.candyUrl is incorrect(404, etc) with something like:
it('should return to an empty array when url is incorrect', sinon.test(function() {
// Fixture is an element I created for testing.
var configStub = SetExample.getCandyConfig(fixture);
var createCandyBoxMock = sinon.mock(config);
createCandyBoxMock.expects('catch');
SetExample. createCandyBox(configStub);
}));
When I do this, term is error => Can't find variable: config.
What did I do wrong? can someone help and explain? I am new to Sinon :( Thx in advance!
You can use sinon.stub() to stub this.getCandies and its resolved/rejected value. And stub Advertisements.pushCandyBox, then make an assertion to check if it has been called or not.
E.g.
SetExample.js:
const Advertisements = require('./Advertisements');
function SetExample() {}
SetExample.getCandies = async function (url) {
return 'your real getCandies implementation';
};
SetExample.createCandyBox = function (config) {
return this.getCandies(config.candyUrl)
.catch(() => {
return {};
})
.then((candies) => {
Advertisements.pushCandyBox(config, candies);
});
};
module.exports = SetExample;
Advertisements.js:
function Advertisements() {}
Advertisements.pushCandyBox = function (config, candies) {
return 'your real pushCandyBox implementation';
};
module.exports = Advertisements;
SetExample.test.js
const SetExample = require('./SetExample');
const Advertisements = require('./Advertisements');
const sinon = require('sinon');
describe('38846337', () => {
describe('#createCandyBox', () => {
afterEach(() => {
sinon.restore();
});
it('should handle error', async () => {
const err = new Error('timeout');
sinon.stub(SetExample, 'getCandies').withArgs('wrong url').rejects(err);
sinon.stub(Advertisements, 'pushCandyBox');
await SetExample.createCandyBox({ candyUrl: 'wrong url' });
sinon.assert.calledWithExactly(SetExample.getCandies, 'wrong url');
sinon.assert.calledWithExactly(Advertisements.pushCandyBox, { candyUrl: 'wrong url' }, {});
});
});
});
unit test result:
38846337
#createCandyBox
✓ should handle error
1 passing (7ms)
-------------------|---------|----------|---------|---------|-------------------
File | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s
-------------------|---------|----------|---------|---------|-------------------
All files | 81.82 | 100 | 42.86 | 81.82 |
Advertisements.js | 66.67 | 100 | 0 | 66.67 | 4
SetExample.js | 87.5 | 100 | 60 | 87.5 | 6
-------------------|---------|----------|---------|---------|-------------------

Categories

Resources