我需要模拟依赖的功能,但仅限于特定的测试用例。在我的其他测试中,我想保持模块不变。我也在嘲笑其他模块。那些需要保持嘲笑。
我尝试了多种方法,因为我已经问过这个问题的多种变体,但由于我需要在没有嘲笑的情况下使用原始模块,所以其他解决方案似乎都没有用......
这是我需要的一个例子
// app.ts
import * as moduleA from 'moduleA';
...
app.post('/signup', async (req, res) => {
...
const hashed = await moduleA.hash(req.body.password);
...
});
export default app;
// app.test.ts
// some mocks
jest.mock('./database', () => ({ ... }));
...
import * as request from 'supertest';
import app from './app;
...
describe('A', () => {
test('Those should work', async () => {
const response = await request(app).post('/signup').send({ password: 'pw' });
expect(response.status).toBe(200);
...
});
// many other tests
test('I need to force hash to crash here', async () => {
// mock moduleA.hash only for this test
const response = request(app).post('/signup').send({ password: 'pw' });
expect(response.status).toBe(500);
});
test('moduleA.hash should be back to its default function', async () => {
// request(app) and moduleA.hash will work properly, not mocked
// ./database stays mocked
});
});
答案 0 :(得分:0)
您可以使用jest.spyOn()
模拟hash
的{{1}}方法,并使用moduleA
将.mockRestore()
方法还原到原始实现。
这是解决方案:
hash
:
app.ts
import express from 'express';
import bodyParser from 'body-parser';
import * as moduleA from './moduleA';
const app = express();
app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json());
app.post('/signup', async (req, res) => {
try {
const hashed = await moduleA.hash(req.body.password);
console.log(hashed);
res.sendStatus(200);
} catch (error) {
res.sendStatus(500);
}
});
export default app;
:
moduleA.ts
export const hash = async (data: string) => {
return 'real hashed value';
};
:
app.spec.ts
覆盖率100%的单元测试结果:
import app from './app';
import request from 'supertest';
import * as moduleA from './moduleA';
describe('app', () => {
test('Those should work', async () => {
const response = await request(app)
.post('/signup')
.send({ password: 'pw' });
expect(response.status).toBe(200);
});
test('I need to force hash to crash here', async () => {
const mockedError = new Error('hash error');
const hashSpy = jest.spyOn(moduleA, 'hash').mockRejectedValueOnce(mockedError);
const response = await request(app)
.post('/signup')
.send({ password: 'pw' });
expect(response.status).toBe(500);
expect(moduleA.hash).toBeCalledWith('pw');
hashSpy.mockRestore();
});
test('moduleA.hash should be back to its default function', async () => {
const logSpy = jest.spyOn(console, 'log');
const response = await request(app)
.post('/signup')
.send({ password: 'pw' });
expect(response.status).toBe(200);
expect(logSpy).toBeCalledWith('real hashed value');
});
});
以下是完整的演示:https://github.com/mrdulin/jest-codelab/tree/master/src/stackoverflow/47540126