这是我第一次前端测试经验。在这个项目中,我使用 Jest 快照测试并且TypeError: window.matchMedia is not a function
在我的组件中出现错误。
我浏览了 Jest 文档,找到了“手动模拟”部分,但我还不知道如何做到这一点。
这是我第一次前端测试经验。在这个项目中,我使用 Jest 快照测试并且TypeError: window.matchMedia is not a function
在我的组件中出现错误。
我浏览了 Jest 文档,找到了“手动模拟”部分,但我还不知道如何做到这一点。
Jest 文档现在有一个“官方”解决方法:
Object.defineProperty(window, 'matchMedia', {
writable: true,
value: jest.fn().mockImplementation(query => ({
matches: false,
media: query,
onchange: null,
addListener: jest.fn(), // Deprecated
removeListener: jest.fn(), // Deprecated
addEventListener: jest.fn(),
removeEventListener: jest.fn(),
dispatchEvent: jest.fn(),
})),
});
我一直在使用这种技术来解决一堆模拟问题。
describe("Test", () => {
beforeAll(() => {
Object.defineProperty(window, "matchMedia", {
writable: true,
value: jest.fn().mockImplementation(query => ({
matches: false,
media: query,
onchange: null,
addListener: jest.fn(), // Deprecated
removeListener: jest.fn(), // Deprecated
addEventListener: jest.fn(),
removeEventListener: jest.fn(),
dispatchEvent: jest.fn(),
}))
});
});
});
或者,如果您想一直模拟它,您可以将您的mocks
文件放入从您的package.json
:
调用的文件中"setupFilesAfterEnv": "<rootDir>/src/tests/mocks.js",
。
我在我的 Jest 测试文件中放置了一个matchMedia存根(在测试之上),它允许测试通过:
window.matchMedia = window.matchMedia || function() {
return {
matches: false,
addListener: function() {},
removeListener: function() {}
};
};
Jest 使用jsdom来创建浏览器环境。但是 JSdom 不支持,window.matchMedia
所以你必须自己创建它。
Jest 的手动模拟与module边界一起工作,即 require / import 语句,因此它们不适合按window.matchMedia
原样模拟,因为它是全局的。
因此,您有两个选择:
定义您自己的本地 matchMedia module,该module导出 window.matchMedia。-- 这将允许您定义一个手动模拟以在您的测试中使用。
定义一个设置文件,将 matchMedia 的模拟添加到全局窗口。
使用这些选项中的任何一个,您都可以使用matchMedia polyfill作为模拟,它至少允许您的测试运行,或者如果您需要模拟不同的状态,您可能想要使用私有方法编写自己的方法,允许您配置它的行为类似于Jestfs
手动模拟