Jest如何禁用换行符匹配校验 跨平台测试忽略换行差异方法
解决方案
原测试失败是因为Jest的toMatchObject对字符串做严格相等比较,Windows系统的换行符\r\n和Linux的\n会被判定为不相等。下面是两种不需要修改原字符串的解决方案:
方案1:全局自定义匹配器(适合大量用例需要)
这个方案不需要修改你原有测试的业务对象,只需要新增全局Jest配置,所有跨系统的用例都可以直接用新匹配器。
步骤1:配置Jest启动文件
在你的jest.config.js(或者jest.config.ts)中添加配置项,指定全局启动文件:
module.exports = { // 其他原有配置... setupFilesAfterEnv: ['<rootDir>/jest.setup.js'], };
步骤2:添加自定义匹配器
在项目根目录新建jest.setup.js,写入如下内容:
expect.extend({ toMatchObjectIgnoringNewlines(received, expected) { // 递归归一化所有换行符,不会修改原对象 const normalizeLineEndings = (value) => { if (typeof value === 'string') { return value.replace(/\r\n/g, '\n'); } if (Array.isArray(value)) { return value.map(normalizeLineEndings); } if (value && typeof value === 'object') { return Object.fromEntries( Object.entries(value).map(([key, val]) => [key, normalizeLineEndings(val)]) ); } return value; }; const normalizedReceived = normalizeLineEndings(received); const normalizedExpected = normalizeLineEndings(expected); const isMatch = this.equals(normalizedReceived, normalizedExpected); if (isMatch) { return { pass: true, message: () => `预期对象不匹配(已忽略换行符差异)`, }; } else { return { pass: false, message: () => `预期对象匹配(已忽略换行符差异)\n实际值:${this.utils.printReceived(normalizedReceived)}\n期望值:${this.utils.printExpected(normalizedExpected)}`, }; } }, });
步骤3:修改测试用例
把原有测试中的toMatchObject替换为新的匹配器即可:
describe("Foo bar", () => { it("should match content without regarding line return", () => { const foo = { content: "foo\nbar" }; const bar = { content: "foo\r\nbar" }; expect(foo).toMatchObjectIgnoringNewlines(bar); }); });
方案2:单次用例使用不对称匹配器(适合少量用例场景)
如果只有个别用例需要处理换行符差异,不需要改全局配置,可以直接用Jest自带的expect.stringMatching实现:
describe("Foo bar", () => { it("should match content without regarding line return", () => { const foo = { content: "foo\nbar" }; const bar = { content: "foo\r\nbar" }; // 把预期字符串中的换行符替换为兼容\r\n和\n的正则 const normalizeNewlineRegex = (str) => new RegExp(str.replace(/\n/g, '\\r?\\n')); expect(foo).toMatchObject({ content: expect.stringMatching(normalizeNewlineRegex(bar.content)) }); }); });
提示:如果你的Node版本高于15,也可以用
str.replaceAll('\n', '\\r?\\n')实现相同效果。
内容的提问来源于stack exchange,提问作者johannchopin
相关产品推荐
相关产品推荐

