如何使用 swr 编写测试
Posted
技术标签:
【中文标题】如何使用 swr 编写测试【英文标题】:How to write test with swr 【发布时间】:2021-08-29 16:22:45 【问题描述】:当用户在输入搜索中键入一些文本时 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>
);
这是我的测试文件
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"));
);
);
【问题讨论】:
【参考方案1】:您可以模拟 axios.get()
方法及其解析/拒绝值,而不是模拟 useSWR
钩子。然后,测试组件的行为,比如返回数据时渲染了什么,没有数据时渲染了什么。
例如
App.tsx
:
import axios from 'axios';
import React from 'react';
import useEffect, useState from 'react';
import useSWR from 'swr';
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
data-testid="search"
id="search-input"
placeholder="search"
onChange=(event) => setQuery(event.target.value)
/>
!repos ? (
<div data-testid="loader">
<h2 id="loading">loading</h2>
</div>
) : (
repos?.items?.map((user) =>
console.log('user: ', user);
return (
<div key=user.id data-testid="repo-item">
user.name
</div>
);
)
)
</div>
);
App.test.tsx
:
import React from 'react';
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';
import axios from 'axios';
describe('test', () =>
beforeEach(() =>
jest.clearAllMocks();
jest.useFakeTimers();
);
it('happy render', () =>
expect(() => render(<App />)).not.toThrow();
);
it('renders after search', async () =>
jest.spyOn(axios, 'get').mockResolvedValueOnce(
data:
items: [
id: 1, name: 'react' ,
id: 2, name: 'jestjs' ,
],
,
);
render(<App />);
userEvent.type(screen.getByTestId('search'), 'vue');
act(() =>
jest.runAllTimers();
);
await waitForElementToBeRemoved(() => screen.getByTestId('loader'));
);
);
测试结果:
PASS examples/67958776/App.test.tsx (8.166 s)
test
✓ happy render (42 ms)
✓ renders after search (58 ms)
console.log
user: id: 1, name: 'react'
at examples/67958776/App.tsx:45:19
at Array.map (<anonymous>)
console.log
user: id: 2, name: 'jestjs'
at examples/67958776/App.tsx:45:19
at Array.map (<anonymous>)
----------|---------|----------|---------|---------|-------------------
File | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s
----------|---------|----------|---------|---------|-------------------
All files | 100 | 80 | 100 | 100 |
App.tsx | 100 | 80 | 100 | 100 | 44
----------|---------|----------|---------|---------|-------------------
Test Suites: 1 passed, 1 total
Tests: 2 passed, 2 total
Snapshots: 0 total
Time: 8.873 s
【讨论】:
以上是关于如何使用 swr 编写测试的主要内容,如果未能解决你的问题,请参考以下文章
在 SWR 中使用 mutate 重新验证数据 - 我应该使用哪个?
使用sws_scale转换视频使用swr_convert转换音频