我的代码如下
const { MyClient } = require('some-service')
const invokeMe = async (input1, input2) => {
const client = new MyClient({
name: 'my-name'
})
return await client.invoke({
input1,
input2
}).catch((err) => {
throw err
})
}
这就是我所拥有的,如何正确模拟该服务并监视其调用内容?
const { MyClient } = require('some-service')
describe('test my client', () => {
it('invoke my client', () => {
const response = {
data: []
}
expect(invokeMe('abc', '123')).resolves.toEqual(response)
expect(MyClient).toBeCalledWith({
input1: 'abc',
input2: '123'
})
})
})
编辑:为什么下面的代码仍然调用原始函数?
it('invoke my client', () => {
const mockInvoke = jest.fn().mockImplementation(() => Promise.resolve({
data: []
}))
const mockMyClient = () => {
return { invoke: mockInvoke }
}
const mockSomeService = {
MyClient: mockMyClient
}
jest.doMock('some-service', () => mockSomeService
...
})
答案 0 :(得分:0)
您可以使用jest.mock(moduleName, factory, options)模拟导入的服务
例如
index.js
:
const { MyClient } = require('./some-service');
const invokeMe = async (input1, input2) => {
const client = new MyClient({
name: 'my-name',
});
return await client
.invoke({
input1,
input2,
})
.catch((err) => {
throw err;
});
};
module.exports = invokeMe;
some-service.js
:
class MyClient {
async invoke(input1, input2) {
return 'real response';
}
}
module.exports = { MyClient };
index.test.js
:
const invokeMe = require('./');
const { MyClient } = require('./some-service');
jest.mock('./some-service', () => {
const mMyClient = { invoke: jest.fn() };
return { MyClient: jest.fn(() => mMyClient) };
});
describe('60008679', () => {
it('should invoke', async () => {
const client = new MyClient();
client.invoke.mockResolvedValueOnce('fake response');
const actual = await invokeMe('a', 'b');
expect(actual).toBe('fake response');
expect(MyClient).toBeCalledWith({ name: 'my-name' });
expect(client.invoke).toBeCalledWith({ input1: 'a', input2: 'b' });
});
it('should handle error', async () => {
const client = new MyClient();
const mError = new Error('some error');
client.invoke.mockRejectedValueOnce(mError);
await expect(invokeMe('a', 'b')).rejects.toThrowError(mError);
expect(MyClient).toBeCalledWith({ name: 'my-name' });
expect(client.invoke).toBeCalledWith({ input1: 'a', input2: 'b' });
});
});
单元测试结果覆盖率100%:
PASS src/stackoverflow/60008679/index.test.js (11.029s)
60008679
✓ should invoke (8ms)
✓ should handle error (4ms)
----------|----------|----------|----------|----------|-------------------|
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: 2 passed, 2 total
Snapshots: 0 total
Time: 12.314s
源代码:https://github.com/mrdulin/jest-codelab/tree/master/src/stackoverflow/60008679