如何在Jest中不保存实例引用对同一值执行多断言测试?
你想要避免保存实例变量同时实现多断言,有几种实用方案:
方案1:用立即执行函数(IIFE)包裹断言
不需要在测试函数顶层定义变量,把实例作为参数传给IIFE,内部完成所有断言——既保证只调用一次makeTest,又避免了额外的变量声明:
describe('Test.makeTest', () => { it('works in simple case', () => { // 用IIFE接收实例,内部做断言 (test => { expect(test).toBeInstanceOf(Test); expect(test).toHaveProperty('id', 0); expect(test).toHaveProperty('config', expect.objectContaining({ a: 1, b: 2 })); })(Test.makeTest({ a: 1, b: 2 })); }); });
方案2:自定义Jest匹配器
如果这类测试场景很多,可以自定义匹配器,把多个断言逻辑封装起来,一次调用完成所有验证:
// 扩展Jest匹配器(可放在测试文件开头或全局配置中) expect.extend({ toBeValidTestInstance(received, expectedConfig) { // 验证是否为Test实例 const isInstance = received instanceof Test; // 验证id(注意:构造函数会自增静态id,所以当前实例id是自增前的值) const idMatches = received.id === Test.id - 1; // 验证config(合并默认配置与传入参数) const configCheck = expect(received.config).toEqual(expect.objectContaining({ ...Test.defaultConfig, ...expectedConfig })); if (isInstance && idMatches && configCheck.pass) { return { pass: true, message: () => `expected ${received} not to be a valid Test instance with config ${expectedConfig}` }; } const messages = []; if (!isInstance) messages.push(`${received} is not an instance of Test`); if (!idMatches) messages.push(`expected id to be ${Test.id - 1}, got ${received.id}`); if (!configCheck.pass) messages.push(configCheck.message()); return { pass: false, message: () => messages.join('; ') }; } }); // 测试用例中直接调用自定义匹配器 describe('Test.makeTest', () => { it('works in simple case', () => { expect(Test.makeTest({ a: 1, b: 2 })).toBeValidTestInstance({ a: 1, b: 2 }); }); });
方案3:使用jest-chain库实现链式断言
如果就是想要链式调用的语法,可以用jest-chain第三方库,它会让Jest的断言方法返回expect实例,支持链式调用:
- 先安装依赖:
npm install --save-dev jest-chain
- 在测试文件中引入并使用:
import 'jest-chain'; describe('Test.makeTest', () => { it('works in simple case', () => { expect(Test.makeTest({ a: 1, b: 2 })) .toBeInstanceOf(Test) .toHaveProperty('id', 0) .toHaveProperty('config', expect.objectContaining({ a: 1, b: 2 })); }); });
注意:如果测试涉及静态id的自增,记得在每个测试用例前重置Test.id = 0,避免测试之间的干扰:
describe('Test.makeTest', () => { beforeEach(() => { Test.id = 0; }); it('works in simple case', () => { // ... 测试逻辑 }); });
内容的提问来源于stack exchange,提问作者Gershom Maes
相关产品推荐
相关产品推荐

