Reputation: 2673
I'm trying to test a few things inside a callback that deals with user input. I'm using the readline module from nodejs
in Jest (similar to the example given in the docs). I can't figure out how I can do assertions inside that callback.
For example: within the callback of readline.createInterface().question()
I'm calling writeFileSync
. I want to test how or if writeFileSync
(or any other function in the callback) is called.
// file.js
const { writeFileSync } = require('fs');
const readline = require('readline');
const copyFile = () => {
const rl = readline.createInterface({
input: process.stdin,
output: process.stdout
});
rl.question('What is the file name?', (userInput) => {
/**
* I want to some assertions on this function.
* For example: with which arguments was it called?
* Or how often is it called?
*/
writeFileSync();
});
}
And in the test
//file.test.js
const { writeFileSync } = require('fs')
jest.mock('fs');
describe('copies files based on user input', () => {
test('calls writeFileSync', () => {
expect(writeFileSync).toHaveBeenCalled();
});
});
The closest I got is:
// __mocks__/readline.js
module.exports = {
createInterface: jest.fn().mockReturnValue(
{
question: jest.fn().mockImplementation(
(question, cb) => {
writeFileSync()
}
)
}
)
}
But with that I am testing the test, I noticed. Anyone know how I can test what's inside the rl.question()
callback? I'll gladly give more info if necessary!
Upvotes: 1
Views: 1374
Reputation: 2673
I've found it: it needs to mock the implementation and call the callback argument (cb
in this case):
// __mocks__/readline.js
module.exports = {
createInterface: jest.fn().mockReturnValue({
question: jest.fn()
.mockImplementationOnce((questionText, cb) => {cb('')}) // test empty arg
.mockImplementationOnce((questionText, cb) => {cb('foo')})
.mockImplementationOnce((questionText, cb) => {cb('bar')})
})
})
};
That returns ''
, foo
, bar
as mocked user input values.
Upvotes: 1
Reputation: 2176
this is called test spies and Sinon.Js has a punch of helpers, check the docs for examples
here, we can spy on fs.writeFileSync before running this test, and then use the spy inside your test.
const spy = sinon.spy(writeFileSync);
then you can assert on the spy call with spy properties such as:
spy.callCount
spy.calledWith()
spy.calledOn()
Upvotes: 1