Unit testing 如何模拟模块';s函数仅用于带有Jest的特定测试
我需要模拟依赖项的函数,但只针对特定的测试用例。在我的其他测试中,我想让模块保持原样。我也在模仿其他模块。这些需要继续被嘲笑 我尝试了多种方法,因为这个问题的许多变体都被问到了,但由于我需要在不被嘲笑时使用原始模块,其他解决方案似乎都不起作用 这是我需要的一个例子Unit testing 如何模拟模块';s函数仅用于带有Jest的特定测试,unit-testing,typescript,jestjs,Unit Testing,Typescript,Jestjs,我需要模拟依赖项的函数,但只针对特定的测试用例。在我的其他测试中,我想让模块保持原样。我也在模仿其他模块。这些需要继续被嘲笑 我尝试了多种方法,因为这个问题的许多变体都被问到了,但由于我需要在不被嘲笑时使用原始模块,其他解决方案似乎都不起作用 这是我需要的一个例子 // app.ts import * as moduleA from 'moduleA'; // ... app.post('/signup', async (req, res) => { // ... cons
// 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
});
});
您可以使用
jest.spyOn()
模拟moduleA
的hash
方法,并使用.mockRestore()
将hash
方法还原为原始实现
以下是解决方案:
app.ts
:
从“express”导入express;
从“body parser”导入bodyParser;
从“/moduleA”导入*作为moduleA;
常量app=express();
use(bodyParser.urlencoded({extended:false}));
use(bodyParser.json());
app.post('/signup',异步(req,res)=>{
试一试{
const hashed=wait moduleA.hash(req.body.password);
log(散列);
res.sendStatus(200);
}捕获(错误){
res.sendStatus(500);
}
});
导出默认应用程序;
模块a.ts
:
export const hash=async(数据:字符串)=>{
返回“实哈希值”;
};
app.spec.ts
:
从“/app”导入应用程序;
从“supertest”导入请求;
从“/moduleA”导入*作为moduleA;
描述('app',()=>{
test('这些应该可以工作',async()=>{
常量响应=等待请求(应用程序)
.post(“/signup”)
.send({密码:'pw'});
expect(response.status),toBe(200);
});
test('我需要在这里强制哈希崩溃',async()=>{
const mockedError=新错误(“哈希错误”);
const hashSpy=jest.spyOn(moduleA,'hash').mockRejectedValueOnce(mockedError);
常量响应=等待请求(应用程序)
.post(“/signup”)
.send({密码:'pw'});
expect(response.status),toBe(500);
expect(moduleA.hash).toBeCalledWith('pw');
hashSpy.mockRestore();
});
测试('moduleA.hash应返回其默认函数',async()=>{
constlogspy=jest.spyOn(控制台,'log');
常量响应=等待请求(应用程序)
.post(“/signup”)
.send({密码:'pw'});
expect(response.status),toBe(200);
expect(logSpy).toBeCalledWith('real hash value');
});
});
100%覆盖率的单元测试结果:
PASS src/stackoverflow/47540126/app.spec.ts
应用程序
✓ 这些应该有效(72毫秒)
✓ 我需要强制哈希在此崩溃(10毫秒)
✓ moduleA.hash应返回其默认函数(14ms)
console.log src/stackoverflow/47540126/app.ts:3569
实散列值
console.log node_modules/jest mock/build/index.js:860
实散列值
------------|----------|----------|----------|----------|-------------------|
文件|%Stmts |%Branch |%Funcs |%Line |未覆盖行|s|
------------|----------|----------|----------|----------|-------------------|
所有文件| 100 | 100 | 100 | 100 ||
附录ts | 100 | 100 | 100 | 100 ||
模A.ts | 100 | 100 | 100 | 100 ||
------------|----------|----------|----------|----------|-------------------|
测试套件:1个通过,共1个
测试:3次通过,共3次
快照:共0个
时间:4.156s,估计5s
以下是完整的演示: