Strange Bug Mocking Window将媒体与React测试库相匹配



我正在测试一个app.js文件,并为此嘲笑window.matchmedia。我已经可以工作了,但我很困惑为什么我的代码可以工作,但玩笑文档中的代码并没有像这里描述的那样,也没有在这个SO问题中指出。

这是我的app.test.js:

import React from "react";
import { render, screen } from "@testing-library/react";
import App from "./app.js";

window.matchMedia = (query) => ({
matches: false,
media: query,
onchange: null,
addEventListener: jest.fn(),
removeEventListener: jest.fn(),
dispatchEvent: jest.fn(),
})
test("renders App component", () => {
render(<App />);
expect(screen.getAllByText("Blog")).toHaveLength(2);
});

这是我的app.js:

import GlobalStyles from "../GlobalStyles/globalStyles.js";
import { ThemeProvider } from "styled-components";
import React, { useState } from "react";
import LandingPage from "../Landing/landing.js";
import About from "../About/about.js";
import Contact from "../Contact/contact.js";
import Blog from "../Blog/blog.js";
import Work from "../Work/work.js";
import DarkModeSwitch from "../DarkModeSwitch/darkModeSwitch.js";
import NotFound from "../NotFound/404.js";
import { lightTheme, darkTheme } from "../Theme/theme.js";
import { BrowserRouter as Router, Routes, Route } from "react-router-dom";
/**
* Main App function. Uses client side routing with React Router and some global styles and theming.
* I've included a dark mode switch here rather than refactoring into a hook since it just feels simpler.
*/
function App() {
// Find user local preferences for dark/light theme
const prefersDark = window.matchMedia("(prefers-color-scheme: dark)").matches;
const initialTheme = prefersDark ? darkTheme : lightTheme;
const [theme, setTheme] = useState(initialTheme);
const [switcher, setSwitcher] = useState(true);
/**
* Handles clicks on the dark mode switch; these themes are then passed into ThemeProvider which injects styles
* into the whole app.
*/
function clickHandler() {
setSwitcher(switcher ? false : true);
setTheme(switcher ? lightTheme : darkTheme);
}
return (
<>
<ThemeProvider theme={theme}>
<GlobalStyles />
<DarkModeSwitch onClick={clickHandler} />
<Router>
<Routes>
<Route path="*" element={<NotFound />} />
<Route exact path="/" element={<LandingPage />}></Route>
<Route exact path="/about" element={<About />}></Route>
<Route exact path="/contact" element={<Contact />}></Route>
<Route exact path="/blog" element={<Blog />}></Route>
<Route exact path="/work" element={<Work />}></Route>
</Routes>
</Router>
</ThemeProvider>
</>
);
}
export default App;

这就是玩笑说你应该做的,当我输入app.test.js时,这对我来说不起作用,尽管我认为它应该:

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(),
})),
});

这是对我有效的解决方案。

我创建了一个名为setupTests.js的文件,其中包含以下函数:

export const mockMatchMedia = () => {
window.matchMedia = query => ({
matches: false,
media: query,
onchange: null,
addListener: jest.fn(), // deprecated
removeListener: jest.fn(), // deprecated
addEventListener: jest.fn(),
removeEventListener: jest.fn(),
dispatchEvent: jest.fn(),
});
};

然后,我在我的测试文件中添加了这个:

beforeAll(() => {
mockMatchMedia();
});

尝试这个

export default global.matchMedia =
global.matchMedia ||
function (query) {
return {
matches: false,
media: query,
onchange: null,
addListener: jest.fn(), // deprecated
removeListener: jest.fn(), // deprecated
addEventListener: jest.fn(),
removeEventListener: jest.fn(),
dispatchEvent: jest.fn(),
};
};

并在所有测试中导入文件

最新更新