javascript - 开玩笑嘲笑测试之间流血,重置并没有解决它
问题描述
测试两个模块,helper
使用render
. 有可能render
抛出,所以我处理它helper
,我想要测试以确保它按预期工作。
当我最初编写测试时,我在测试本身中编写了该测试所需的内容,包括模拟,使用jest.doMock
. 一旦所有的测试都通过了,我想重构以尽可能地分享模拟。
所以这段代码很好用:
test('throws', async () => {
jest.doMock('./render', () => jest.fn(async () => { throw new Error('mock error'); }));
const helper = require('./helper');
expect(async () => { helper(); }).rejects.toThrow('mock error');
expect(log_bug).toHaveBeenCalled();
});
test('succeeds', async () => {
jest.doMock('./render', () => jest.fn(async () => 'rendered result'));
const helper = require('./helper');
expect(await helper()).toEqual(true); //helper uses rendered result but doesn't return it
expect(log_bug).not.toHaveBeenCalled();
});
然而,这不是仅有的两个测试,到目前为止,大多数其他模拟渲染的测试都希望它返回其成功状态。我试图将成功的用例重构为一个文件,__mocks__/render.js
如下所示:
// __mocks__/render.js
module.exports = jest.fn(async () => 'rendered result');
然后将我的测试重构为更干燥:
//intention: shared reusable "success" mock for render module
jest.mock('./render');
beforeEach(() => {
jest.resetModules();
jest.resetAllMocks();
});
test('throws', async () => {
//intention: overwrite the "good" render mock with one that throws
jest.doMock('./render', () => jest.fn(async () => { throw new Error('mock error'); }));
const helper = require('./helper');
expect(async () => { await helper(); }).rejects.toThrow('mock error');
expect(log_bug).toHaveBeenCalled();
});
test('succeeds', async () => {
//intention: go back to using the "good" render mock
const helper = require('./helper');
expect(await helper()).toEqual(true); //helper uses rendered result but doesn't return it
expect(log_bug).not.toHaveBeenCalled();
});
使用这个更新的测试代码,错误记录测试仍然按预期工作——模拟被覆盖以导致它抛出——但是对于下一个测试,错误再次被抛出。
如果我颠倒这些测试的顺序以便模拟覆盖在最后,那么就不会发生故障,但这显然不是正确的答案。
我究竟做错了什么?为什么我不能在用 覆盖它后让我的模拟正确重置doMock
?doMock 文档确实说明了我正在尝试做的事情,但他们没有显示将其与普通的手动模拟混合。
解决方案
啊哈!我不断挖掘并发现这个有点相似的 Q+A,这导致我尝试这种方法,而不是使用jest.doMock
覆盖测试内部:
//for this one test, overwrite the default mock to throw instead of succeed
const render = require('./render');
render.mockImplementation(async () => {
throw new Error('mock error');
});
有了这个,无论它们运行什么顺序,测试都通过了!
推荐阅读
- c# - 使用 C# 和 Selenium 的 Crawlera/Zyte 代理身份验证
- docker - 使用 docker 安装 google-chrome-stable
- postgresql - pgadmin 4,导入 csv,错误代码 1,没有错误信息
- python-3.x - 将 Python 列表中字符串中第 N 个字符之前和之后的字符大写
- c - 函数“rand_r”的隐式声明
- javascript - Discord.js 石头剪刀布命令不做任何事情,即使没有明显的错误
- rest - 使用 Twilio 发送 SMS 时出现 TwilioRestException
- c - 获得用户输入后,最后一个 printf() 根本不打印
- python - 转移数据组
- codeigniter - Codeigniter PHPMailer 如何使用输入字段获取地址和邮件内容?