Mii*_*nny 5 reactjs jestjs react-testing-library react-hooks swr
当用户在输入搜索中输入一些文本时,必须删除 data-testid = 'loading',现在控制台返回 Unable to find an element by: [data-testid="loading"] 有人可以建议我用 swr 或建议编写测试对我来说如何模拟来自 swr 的响应
这是我的组件文件
import axios from "axios";
import { useEffect, useState } from "react";
import useSWR from "swr";
import "./styles.css";
const useDebounce = (newValue) => {
const [value, setValue] = useState("");
useEffect(() => {
const timeout = setTimeout(() => {
setValue(newValue);
}, 500);
return () => clearTimeout(timeout);
}, [newValue]);
return value;
};
export const fetcher = async (url) => {
const { data } = await axios.get(url);
return data;
};
export default function App() {
const [query, setQuery] = useState("react");
const searchQuery = useDebounce(query);
const { data: repos } = useSWR(
`https://api.github.com/search/repositories?q=${searchQuery}&per_page=1&page=1`,
fetcher
);
return (
<div className="App">
<h1>Hello CodeSandbox</h1>
<h2>Start editing to see some magic happen!</h2>
<input
testId="search"
data-testid="search"
id="search-input"
placeholder="search"
onChange={(event) => setQuery(event.target.value)}
/>
{!repos ? (
<div data-testid="loader" testId="loader">
<h2 id="loading">loading</h2>
</div>
) : (
repos?.items?.map((user) => {
return (
<div
data-testid="repo-item"
style={{
margin: "1rem",
height: "40px",
background: "lightpink"
}}
>
{user.name}
</div>
);
})
)}
</div>
);
}
Run Code Online (Sandbox Code Playgroud)
这是我的测试文件
import {
render,
screen,
waitForElementToBeRemoved
} from "@testing-library/react";
import userEvent from "@testing-library/user-event";
import App from "./App";
import { act } from "react-dom/test-utils";
describe("test", () => {
beforeEach(() => {
jest.resetAllMocks();
jest.useFakeTimers();
});
it("happy render", () => {
expect(() => render(<App />)).not.toThrow();
});
it("renders after search", async () => {
render(<App />);
userEvent.type(screen.getByTestId("search"), "vue");
act(() => {
jest.runAllTimers();
});
await waitForElementToBeRemoved(() => screen.getByTestId("loader"));
});
});
Run Code Online (Sandbox Code Playgroud)
您可以模拟axios.get()方法及其已解析/拒绝的值,而不是模拟useSWR挂钩。然后,测试组件的行为,例如返回数据时呈现的内容以及没有可用数据时呈现的内容。
例如
\nApp.tsx:
import axios from 'axios';\nimport React from 'react';\nimport { useEffect, useState } from 'react';\nimport useSWR from 'swr';\n\nconst useDebounce = (newValue) => {\n const [value, setValue] = useState('');\n useEffect(() => {\n const timeout = setTimeout(() => {\n setValue(newValue);\n }, 500);\n return () => clearTimeout(timeout);\n }, [newValue]);\n return value;\n};\n\nexport const fetcher = async (url) => {\n const { data } = await axios.get(url);\n return data;\n};\n\nexport default function App() {\n const [query, setQuery] = useState('react');\n const searchQuery = useDebounce(query);\n const { data: repos } = useSWR(\n `https://api.github.com/search/repositories?q=${searchQuery}&per_page=1&page=1`,\n fetcher\n );\n return (\n <div className="App">\n <h1>Hello CodeSandbox</h1>\n <h2>Start editing to see some magic happen!</h2>\n <input\n data-testid="search"\n id="search-input"\n placeholder="search"\n onChange={(event) => setQuery(event.target.value)}\n />\n {!repos ? (\n <div data-testid="loader">\n <h2 id="loading">loading</h2>\n </div>\n ) : (\n repos?.items?.map((user) => {\n console.log('user: ', user);\n return (\n <div key={user.id} data-testid="repo-item">\n {user.name}\n </div>\n );\n })\n )}\n </div>\n );\n}\nRun Code Online (Sandbox Code Playgroud)\nApp.test.tsx:
import React from 'react';\nimport { render, screen, waitForElementToBeRemoved } from '@testing-library/react';\nimport userEvent from '@testing-library/user-event';\nimport App from './App';\nimport { act } from 'react-dom/test-utils';\nimport axios from 'axios';\n\ndescribe('test', () => {\n beforeEach(() => {\n jest.clearAllMocks();\n jest.useFakeTimers();\n });\n it('happy render', () => {\n expect(() => render(<App />)).not.toThrow();\n });\n\n it('renders after search', async () => {\n jest.spyOn(axios, 'get').mockResolvedValueOnce({\n data: {\n items: [\n { id: 1, name: 'react' },\n { id: 2, name: 'jestjs' },\n ],\n },\n });\n render(<App />);\n userEvent.type(screen.getByTestId('search'), 'vue');\n act(() => {\n jest.runAllTimers();\n });\n await waitForElementToBeRemoved(() => screen.getByTestId('loader'));\n });\n});\nRun Code Online (Sandbox Code Playgroud)\n测试结果:
\n PASS examples/67958776/App.test.tsx (8.166 s)\n test\n \xe2\x9c\x93 happy render (42 ms)\n \xe2\x9c\x93 renders after search (58 ms)\n\n console.log\n user: { id: 1, name: 'react' }\n\n at examples/67958776/App.tsx:45:19\n at Array.map (<anonymous>)\n\n console.log\n user: { id: 2, name: 'jestjs' }\n\n at examples/67958776/App.tsx:45:19\n at Array.map (<anonymous>)\n\n----------|---------|----------|---------|---------|-------------------\nFile | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s \n----------|---------|----------|---------|---------|-------------------\nAll files | 100 | 80 | 100 | 100 | \n App.tsx | 100 | 80 | 100 | 100 | 44 \n----------|---------|----------|---------|---------|-------------------\nTest Suites: 1 passed, 1 total\nTests: 2 passed, 2 total\nSnapshots: 0 total\nTime: 8.873 s\nRun Code Online (Sandbox Code Playgroud)\n
| 归档时间: |
|
| 查看次数: |
180 次 |
| 最近记录: |