我正在使用 Material-UI 和 React 来构建一个Dropdown组件。
下拉列表.tsx
import React from "react";
import ClickAwayListener from "@material-ui/core/ClickAwayListener";
import Grow, { GrowProps } from "@material-ui/core/Grow";
import Input from "@material-ui/core/Input";
import MenuList from "@material-ui/core/MenuList";
import Paper from "@material-ui/core/Paper";
import Popper from "@material-ui/core/Popper";
import MenuItem from "@material-ui/core/MenuItem";
export default function Dropdown(props: {
onSearch: (suggestion: string) => void;
}) {
const [searchText, setSearchText] = React.useState("");
const [open, setOpen] = React.useState(false);
let searchElement: null | HTMLElement = null;
const onSearchTextChange = (event: React.ChangeEvent<HTMLInputElement>) => {
setSearchText(event.target.value); …Run Code Online (Sandbox Code Playgroud) menuitem typescript reactjs material-ui react-testing-library
我想测试当我在输入(inputA)中键入一个值时,另一个输入(inputB)会更新为一个值。
inputA 接受邮政编码,例如:“10999”,在 inputB 显示位置后:“Berlin”
这适用于实际的应用程序,我输入 inputA,然后 inputB 会更新。
当 ome 在 inputA 上键入时,会调度一个操作,然后 inputB 从 redux 状态获取一个新值。
这是我的测试代码,您知道为什么它在测试中不使用“Ort”占位符更新输入,但在实际应用程序中却这样做吗?
import { render, withIntl, withStore, configureStore, withState } from "test-utils-react-testing-library";
import { screen, fireEvent, withHistory, withRoute, within } from "@testing-library/react";
import configureMockStore from 'redux-mock-store';
import ProfileForm from "./ProfileForm";
import PersonalDetails from "../PersonalDetails/PersonalDetails";
const STATE = {
locations: { locations: {} },
streets: { streets: {} },
password: {}
};
const mockStore = configureMockStore();
const STORE = mockStore({
streets: {
isFetching: false, …Run Code Online (Sandbox Code Playgroud) 我试图弄清楚如何使用 jest 和 React 测试库来测试作为 props 给出的回调,以对功能组件做出反应。
示例场景:我正在测试一个呈现模式的组件。当用户单击模式上的“关闭”按钮时,父组件将隐藏模式。所以逻辑是这样的:
const ParentComp = () => {
const [openModal, setOpenModal] = useState(false);
return (
<>
<MyModal showModal={openModal} onClose={() => setOpenModal(false)} />
<button data-testid="open-modal-button" onClick={()=> setOpenModal(true)}>Test</button>
</>
}
const MyModal = ({showModal, onClose}) => {
return (
{showModal && <>
<div>This is a modal</div>
<button data-testid="close-modal-button" onClick={onClose}>Close</button>
</>
}
}
Run Code Online (Sandbox Code Playgroud)
我在父组件的测试中模拟模态,因为我不想依赖实际的模态组件。使用 React 测试库,如何触发父组件中的 onClose 以便测试 setOpenModal(false)?
jest.mock('../MyModal');
beforeEach(() => {
MyModal.mockImplementation(() => <div data-testid="my-modal" />);
});
it('should close the modal' () => {
const …Run Code Online (Sandbox Code Playgroud) 我正在重构项目中的一些代码,将类组件传递给功能组件。在我的测试中出现了一些错误。
我有一个名为“MenuWeb”的组件,我现在正在其中使用 redux hooks。
这就是测试代码
describe('Testing MenuWeb', () => {
it('should render Menu Web correctly', () => {
const wrapper = shallow(<MenuWeb store={store} />)
expect(wrapper).toMatchSnapshot()
})
Run Code Online (Sandbox Code Playgroud)
这就是我收到的错误:
我知道酶不支持钩子,但我不知道如何使用现在的反应测试库重构这个测试。我尝试按照消息所述使用提供者进行包装,但它不起作用,或者我做错了什么。
我想看看是否至少呈现了部分文本。
<li>
Click here
<a
id="myLink"
className="xxxxx"
target="_blank"
rel="noreferrer"
href="https://www.aaa.com"
>
to open xxx.
</a>
</li>
Run Code Online (Sandbox Code Playgroud)
测试失败并显示:
xxxxxx.getByText('Click here')
Run Code Online (Sandbox Code Playgroud)
但如果“单击此处”只是该文本,则效果很好
我想知道为什么我需要将获取模拟逻辑放入我的测试中才能使其工作。
这是一个简单的例子:
使用 useEffect 内部的 fetch 进行测试的组件,并在响应后更新状态:
// Test.jsx
import React, {useEffect, useState} from 'react'
export const Test = () => {
const [description, setDescription] = useState<string | null>(null)
const fetchData = async () => {
const response = await fetch('https://dummyendpoint/');
const parsed = await response.json();
const description = parsed.value;
setDescription(description);
}
useEffect(() => {
fetchData();
}, [])
return (
<div data-testid="description">
{description}
</div>
)
};
export default Test;
Run Code Online (Sandbox Code Playgroud)
测试逻辑:
// Test.test.js
import React from 'react';
import {render, screen} from …Run Code Online (Sandbox Code Playgroud) 我有一个可选择的框,因此我想为该框添加两个测试 ID,一个用于测试框的类型,另一个用于测试框是否被选中。我应该在一个 data-testid 中添加两个 data-testid 属性还是两个关键字?当涉及到 Cypress 或 React-testing-library 时,最佳实践是什么?
<div data-testid="box-user" data-testid="box-user-active">
Run Code Online (Sandbox Code Playgroud)
与
<div data-testid="box-user box-user-active">
Run Code Online (Sandbox Code Playgroud)
我知道还有其他方法可以检查该框是否被选中,但是还有很多其他用例,添加两个测试 ID 会让事情变得更容易。
describe('some set of related functionality', () => {
const onSelect = jest.fn();
const Wrapper = render(
<MyComponent onSelect={onSelect)} />
);
afterEach(() => {
onSelect.mockReset();
});
it('tests something', async () => {
userEvent.click(await Wrapper.findByText('some-text'));
expect(onSelect).toBeCalledWith('something');
});
it('also tests something on the same component very related to closest describe block', async () => {
userEvent.click(await Wrapper.findByText('some-other-text'));
expect(onSelect).toBeCalledWith('some-other-thing');
});
});
Run Code Online (Sandbox Code Playgroud)
所以这里的想法是在一些测试之间重用包装器并查询该包装器而不是在 global 中清理的全局屏幕afterEach。
我喜欢默认行为,但我认为在某些测试之间重用包装器可能很有用,例如加快某些测试速度或缩短测试时间。
目前的替代方案是在一条语句中编写许多断言(实际上是许多测试)it。例如它可以是这样的
it('tests some set of related functionality', () => …Run Code Online (Sandbox Code Playgroud) 希望你们在这种情况下一切顺利:) 在 React 应用程序的 App 组件中运行渲染测试时,我在 useContext 中遇到错误。
这是上下文 api:
const { userId } = useContext(UserContext);
这是错误:
TypeError:无法解构“(0,_react.useContext)(...)”的属性“userId”,因为它未定义。
35 | 35 const { userId } = useContext(UserContext);
该对象一开始是未定义的,因为它是获取 userId 的 API 调用。登录后,用户 ID 可用。因此,在开发中运行时,它可以正常工作,但在运行测试时,它会显示此错误。
最后是 UserContext 组件:
导出 const UserContext = createContext();
const UserProvider = ({ children }) => {
const [userId, setUserId] = useState("");
const getUserId = async () => {
if (token) {
await axios
.get(`${baseURL}/auth/user`, {
headers: {
authorization: token
}
})
.then(function …Run Code Online (Sandbox Code Playgroud)unit-testing reactjs jestjs react-testing-library use-context
我正在使用react-testing-library和jest为React编写测试,并且在弄清楚当另一个文件导入存储时如何为我的redux存储设置preloadedState时遇到一些问题。
我有一个功能可以像这样设置我的商店
商店.ts
export const history = createBrowserHistory()
export const makeStore = (initalState?: any) => configureStore({
reducer: createRootReducer(history),
preloadedState: initalState
})
export const store = makeStore()
Run Code Online (Sandbox Code Playgroud)
和另一个像这样的js文件
实用程序.ts
import store from 'state/store'
const userIsDefined = () => {
const state = store.getState()
if (state.user === undefined) return false
...
return true
}
Run Code Online (Sandbox Code Playgroud)
然后我有一个看起来像这样的测试:
utils.test.tsx( renderWithProvider 基本上是一个渲染函数,它也将我的组件包装在渲染组件中,请参阅: https: //redux.js.org/recipes/writing-tests#connected-components)
describe("Test", () => {
it("Runs the function when user is defined", async () => {
const store = makeStore({ user: …Run Code Online (Sandbox Code Playgroud) reactjs ×7
jestjs ×6
redux ×3
javascript ×2
typescript ×2
unit-testing ×2
cypress ×1
enzyme ×1
material-ui ×1
menuitem ×1
react-hooks ×1
testing ×1
use-context ×1