[英]node + jest + mocking event handler callbacks
I have a function in my Node.js code which I am trying to test but I want to mock out processStreamData
:我的 Node.js 代码中有一个 function ,我正在尝试测试它,但我想模拟出
processStreamData
:
async functionToTest(stream) {
// Run some checks on the stream here
stream.on('data', async (data) => {
// Run some checks on the data here
await this.processStreamData(data);
}).on('finish', () => {
// Do some processing here
resolve();
});
}
async processStreamData(data) {
...
}
Here is my test:这是我的测试:
test('functionToTest success', async (testCase) => {
try {
let readStream = fs.createReadStream(`${DATA_DIR}/genericCsv.csv`);
jest.spyOn(myClass, "processStreamData").mockImplementation();
await expect(myClass.functionToTest(readStream)).resolves.toEqual(undefined);
await expect(myClass.processStreamData).toBeCalledWith(expect.anything());
testCase();
} catch(exception) {
console.log(exception);
testCase.fail(new Error(`Test failed${exception}`));
};
});
It seems like because processStreamData
is inside an event handler, the original function (rather than the mock) is called.似乎因为
processStreamData
在事件处理程序中,所以调用了原始的 function (而不是模拟)。
I've also tried mocking the function via我也试过 mocking function 通过
myClass.processStreamData = jest.fn.mockImplementation()
which didn't work.这没有用。 The original function was still called.
原来的 function 仍然被调用。
I've done some googling and am well-aware that jest historically has had limitations around this https://github.com/facebook/jest/issues/207 but does this still apply?我已经进行了一些谷歌搜索,并且很清楚 jest 在历史上对这个https://github.com/facebook/jest/issues/207有限制,但这仍然适用吗? If not, can someone hand-hold me through the process of how I should set up my mock so it can be used?
如果没有,有人可以帮助我完成我应该如何设置我的模拟以便可以使用它的过程吗?
Here is a unit test solution:这是一个单元测试解决方案:
index.ts
: index.ts
:
export class SomeClass {
async functionToTest(stream) {
// Run some checks on the stream here
stream
.on('data', async data => {
// Run some checks on the data here
await this.processStreamData(data);
})
.on('finish', () => {
// Do some processing here
Promise.resolve();
});
}
async processStreamData(data) {
console.log(data);
}
}
index.spec.ts
: index.spec.ts
:
import fs, { ReadStream } from 'fs';
import path from 'path';
import { SomeClass } from './';
const myClass = new SomeClass();
const DATA_DIR = './.tmp';
afterEach(() => {
jest.restoreAllMocks();
});
test('functionToTest success', async () => {
const readStream: ReadStream = fs.createReadStream(path.resolve(__dirname, `${DATA_DIR}/genericCsv.csv`));
const events: { [event: string]: (...args: any[]) => void } = {};
jest.spyOn(readStream, 'on').mockImplementation((event: string, listener: (...args: any[]) => void) => {
events[event] = listener;
return readStream;
});
jest.spyOn(myClass, 'processStreamData');
await expect(myClass.functionToTest(readStream)).resolves.toEqual(undefined);
events.data('fake data');
expect(myClass.processStreamData).toBeCalledWith('fake data');
});
test('functionToTest finish', async () => {
const readStream: ReadStream = fs.createReadStream(path.resolve(__dirname, `${DATA_DIR}/genericCsv.csv`));
const events: { [event: string]: (...args: any[]) => void } = {};
jest.spyOn(readStream, 'on').mockImplementation((event: string, listener: (...args: any[]) => void) => {
events[event] = listener;
return readStream;
});
jest.spyOn(Promise, 'resolve');
await expect(myClass.functionToTest(readStream)).resolves.toEqual(undefined);
events.finish();
expect(Promise.resolve).toBeCalledTimes(1);
});
Unit test result with 100% coverage:覆盖率 100% 的单元测试结果:
PASS src/stackoverflow/58244855/index.spec.ts (6.502s)
✓ functionToTest success (14ms)
✓ functionToTest finish (1ms)
console.log src/stackoverflow/58244855/index.ts:3320
fake data
----------|----------|----------|----------|----------|-------------------|
File | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s |
----------|----------|----------|----------|----------|-------------------|
All files | 100 | 100 | 100 | 100 | |
index.ts | 100 | 100 | 100 | 100 | |
----------|----------|----------|----------|----------|-------------------|
Test Suites: 1 passed, 1 total
Tests: 2 passed, 2 total
Snapshots: 0 total
Time: 7.544s
Source code: https://github.com/mrdulin/jest-codelab/tree/master/src/stackoverflow/58244855源码: https://github.com/mrdulin/jest-codelab/tree/master/src/stackoverflow/58244855
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.