Reputation: 1181
I'm trying to test the below function
getVal(process) {
test.on('data', async data => {
try {
for (const val of data) {
await process(val);
console.log('processed')
}} catch (e) {}
});
test.on('error', err => {
console.log('error', err)
});
}
process(payload) {
return new Promise(resolve=>{.....})
};
Jest test: // in beforeEach
mockData =[an array containing 10 values]
onSpy = jest
.fn()
.mockImplementationOnce(async (data, callback) => {
callback(mockData);
})
.mockImplementationOnce((error, callback) => {
callback(mockErr);
});
it('should trigger callback once per message', async () => {
await xyz.getVal(process);
await expect(process).toHaveBeenCalledTimes(10);
});
I expect the process()
to be called 10 times since the data is sent 10 times. However it's called only 2 times when I assert but when I put a console.log in the function itself and run the test, that gets called 10 times.
I'm not sure what's wrong. Appreciate any help.
Upvotes: 5
Views: 31846
Reputation: 45810
The issue is that calling await
on xyz.getVal
doesn't actually do anything since getVal
is a synchronous function that just sets up the event listeners...
...so the asynchronous events haven't finished processing by the time the expect
runs and fails.
It looks like you've already got a spy on test.on
.
Instead of mocking its implementation, just use it to get the callback function.
Then you can call and await
the callback function directly:
// in beforeEach
mockData = [an array containing 10 values]
onSpy = jest.fn();
it('should trigger callback once per message', async () => {
xyz.getVal(process);
const callback = onSpy.mock.calls[0][1]; // <= get the callback (second argument of the first call to test.on)
await callback(mockData); // <= call and await the callback directly
expect(process).toHaveBeenCalledTimes(10); // Success!
});
Upvotes: 8