我正在为我们的 React 应用程序编写单元测试。使用 recharts 库创建的组件很少。
import { COLORS } from 'constants/colors.constants';
import { FC } from 'react';
import { Bar, BarChart, CartesianGrid, ResponsiveContainer, Tooltip, XAxis, YAxis } from 'recharts';
import { MonthlyApplication } from 'store/stats/types/stats-state.types';
const BarChartComponent: FC<BarChartComponentProps> = ({
data,
barSize,
height,
color,
allowDecimals,
}) => (
<ResponsiveContainer width='100%' height={height}>
<BarChart data={data}>
<CartesianGrid strokeDasharray='10 10 ' />
<XAxis dataKey='month' />
<YAxis allowDecimals={allowDecimals} />
<Tooltip />
<Bar dataKey='count' fill={color} barSize={barSize} />
</BarChart>
</ResponsiveContainer>
);
type BarChartComponentProps = {
data: MonthlyApplication[]; …Run Code Online (Sandbox Code Playgroud) javascript reactjs react-native react-testing-library react-native-testing-library
我有一个自定义钩子,可以在挂载时进行 API 调用并处理状态(isLoading、isError、数据、重新获取);
钩子非常简单:
const useFetch = (endpoint, options) => {
const [data, setData] = useState(null);
const [error, setError] = useState(null);
const [isLoading, setIsLoading] = useState(true);
const [trigger, setTrigger] = useState(true);
const triggerSearch = () => {
setTrigger(!trigger);
};
useEffect(() => {
const fetchData = async () => {
try {
const response = await fetch(
`${process.env.API_URL}${endpoint}`
);
const json = await response.json();
setData(json);
setIsLoading(false);
} catch (error) {
setError(error);
setIsLoading(false);
}
};
fetchData();
}, [endpoint, trigger]);
return {
data, …Run Code Online (Sandbox Code Playgroud) 有人看到这里的问题吗?如果我在更改时将检查状态设置为有效。但我不想复制检查的状态数据并观察它的每一个道具的变化。
父组件获取最新的检查信息并将其置于自己的状态中,如果父组件 isChecked 更改,则 FormCheckBox isChecked 更改。我认为,它是异步工作的,当我到达测试代码的最新行时,父更新没有完成,所以我看到过时的 isChecked。
export default function FormCheckBox(props: IFormCheckBoxProps) {
const { onChange, label, isChecked, error, errorModelLabel = '' } = props
const handleChange = (event: React.ChangeEvent<HTMLInputElement>) => {
onChange(event.currentTarget.checked)
}
const errorMsg = getFormErrorMsg(error, errorModelLabel)
return (
<FormGroup
as={Row}
className={cx('mb-3', { 'is-invalid': errorMsg })}
controlId="catalogDescription"
data-testid="slvy-formcheckbox"
>
<FormLabel column className="d-flex align-items-center justify-content-end fw-bold" sm={2}>
{label}
</FormLabel>
<Col className="d-flex align-items-center" sm={10}>
<input
checked={isChecked}
className={cx('checkbox', { 'is-invalid': errorMsg })}
type="checkbox"
onChange={handleChange}
/>
<Form.Control.Feedback type="invalid">{errorMsg}</Form.Control.Feedback>
</Col>
</FormGroup>
) …Run Code Online (Sandbox Code Playgroud) 我有一个React+vite应用程序,我正在为其编写测试以涵盖应用程序启动时的前端路由重定向逻辑。
路由由 v6 处理react-router,所有与路由相关的组件都包装在React.lazy. 测试是由运行的vitest,我正在使用react-testing-library助手
所有测试都是相似的,看起来像这样
it('Redirects from app root to red room if the user has a red shirt', async () => {
getUser.mockReturnValue(redShirtUser);
render(MyTestedComponent, { wrapper });
await waitFor(() => expect(screen.getByText('Welcome to the red room'));
expect(history.location.pathname).toBe('/red-room');
});
Run Code Online (Sandbox Code Playgroud)
然而,其中一项测试花费的时间比其他测试要长得多,甚至waitFor超时。我可以指定更长的超时waitFor,但它仍然无法在 CI 上可靠地运行。如果测试是其文件中唯一的测试/唯一正在执行的测试,也会发生这种情况。
我已经将缓慢的部分(通过调试的魔力console.log)缩小为惰性import()语句 - 导入并执行模块需要花费很多时间(秒)。
我该如何调试这个?是否有已知的因素会导致(惰性)导入变慢?
我在反应测试库中使用 rerender 和 renderHook 。最近将 React 版本升级到 18。在其中一个测试用例中出现以下错误。
console.error 警告:ReactDOM.render 在 React 18 中不再支持。请改用 createRoot。在您切换到新 API 之前,您的应用程序的行为就像运行 React 17 一样。了解更多信息:https ://reactjs.org/link/switch-to-createroot
重新渲染();renderHook(() => abc());
因为,我不使用渲染,为什么警告将重新渲染和 renderHook 指向渲染。
您能指出如何进一步挖掘这个问题吗?
成分:
const MyComponent = props => {
const {price} = props;
const result1 = useResult(price);
return (
<div>...</div>
)
}
Run Code Online (Sandbox Code Playgroud)
定制挂钩:
export const useResult = (price) => {
const [result, setResult] = useState([]);
useEffect(() => {
const data = [{price: price}]
setResult(data);
}, [price]);
return result;
};
Run Code Online (Sandbox Code Playgroud)
开玩笑测试:
it('should ...', async () => {
render(
<MyComponent price={300}/>)
)
await waitFor(() => {
expect(...).toBeInTheDocument();
});
});
Run Code Online (Sandbox Code Playgroud)
上面的代码确实发生的是MyComponent,当运行测试时,仅渲染一次而不是两次(当应用程序运行时)。初始渲染后,其中result1是一个空数组,useEffect正在useResult运行,并且由于 导致状态发生变化setResult(data),我应该期望MyComponent …
我是 React 测试库的新手。我想测试位于 Login.tsx 组件内的登录表单。
`
const Login = () => {
useYupTranslation();
const dispatch = useAppDispatch();
const { t } = useTranslation(["common", "loginPage", "buttons", "loginPage"]);
useDocumentTitle(t("loginPage:header"));
const navigate = useNavigate();
const location = useLocation();
const token = getTokenFromLocalStorage();
const refreshToken = getRefreshTokenFromLocalStorage();
const currentTime = new Date().getTime();
const decodedAccessToken = decodeToken<DecodedToken["accessToken"]>(token!);
const decodedRefreshToken = decodeToken<DecodedToken["refreshToken"]>(refreshToken!);
useEffect(() => {
if (location.search === "?token-expired") {
toast.error(t("loginPage:logoutNotification"), {
autoClose: false,
});
}
}, [location, t, token]);
const loginValidation = Yup.object({
email: Yup.string().email().required(), …Run Code Online (Sandbox Code Playgroud) 我正在使用 React 测试库来测试组件,并且遇到了一个场景,其中唯一似乎可以消除警告
Warning: An update to MyComponent inside a test was not wrapped in act(...).
Run Code Online (Sandbox Code Playgroud)
是通过使用
await act(async () => {});
Run Code Online (Sandbox Code Playgroud)
现在,我承认我并不完全理解什么act()是,有时我会尝试使用act()和的不同变体waitFor()的不同变体,异步和非异步,直到警告消失,但这次我无法在不使用的情况下做到这一点空回调,感觉不对,我确信将来会失败,所以我想更好地了解发生了什么。
我创建了一个显示该问题的沙箱: https: //codesandbox.io/s/cranky-ben-kfxm7q。
一些注意事项:
<Tooltip />似乎很重要,尽管我们没有在测试中断言它data在效果之外进行更改,从而使效果再次运行这个例子可能没有多大意义,但请理解,我必须将我的实际组件简化到仍然显示警告的最低限度。理想情况下,我正在寻找一种无需修改组件即可修复测试的方法,因为更改实际组件可能并不那么容易。
我已尽最大努力找出问题所在,但到目前为止我尝试的一切都不起作用。
这就是我的 App.js 的样子:
import './App.css';
import {ChakraProvider} from '@chakra-ui/react'
import Header from './components/Header'
import Hero from './components/Hero'
import Highlights from './components/Highlights.js'
import About from './components/About.js'
import Footer from './components/Footer.js'
import Reserve from './components/Reserve.js'
import '@fontsource/karla'
import '@fontsource/markazi-text'
import theme from './theme'
import { Routes, Route,} from "react-router-dom";
function Homepage(){
return(
<>
<Hero/>
<Highlights/>
<About/>
<Footer/>
</>
)
}
function App() {
return (
<ChakraProvider theme={theme}>
<Header/>
<main>
<Routes>
<Route path='/' element={<Homepage/>}/>
<Route path='/Reservations' element={<Reserve/>}/>
</Routes>
</main>
</ChakraProvider>
);
} …Run Code Online (Sandbox Code Playgroud) 我正在使用 React 18、React 测试库 14.0.0 和 React Query 3.3。在浏览器(真实用户)上下文中,一切都像魅力一样工作。但在测试时我遇到了一些问题。
我的组件(简化):
import { useQuery } from "react-query"
export const Dashboard = () => {
const { data } = useQuery(...)
const { data: project } = useQuery(...)
return <div data-testid="project-name">{project.name}</div>
Run Code Online (Sandbox Code Playgroud)
考试:
import { ReactElement, Suspense } from "react"
import { render } from "@testing-library/react"
import { QueryClient } from "react-query"
export const testRenderer = (test: ReactElement) =>
render(<Suspense fallback={<div>loading...</div>}>
<QueryClientProvider
client={
new QueryClient({
defaultOptions: {
queries: {
suspense: true,
},
}, …Run Code Online (Sandbox Code Playgroud) javascript testing reactjs react-testing-library react-query
reactjs ×10
javascript ×4
react-hooks ×3
testing ×2
jestjs ×1
react-18 ×1
react-native ×1
react-native-testing-library ×1
react-query ×1
rerender ×1
typescript ×1
unit-testing ×1
vitest ×1