是否可以等待组件渲染?反应测试 Library/Jest
Is it possible to wait for a component to render? React Testing Library/Jest
我有一个组件。它有一个按钮。按下按钮后,我将使用 setState 函数更改按钮文本(颜色)的样式。当我测试更改的组件时,测试失败,因为更改是异步发生的。我想做这里给出的事情 (https://testing-library.com/docs/dom-testing-library/api-async/)
const button = screen.getByRole('button', { name: 'Click Me' })
fireEvent.click(button)
await screen.findByText('Clicked once')
fireEvent.click(button)
await screen.findByText('Clicked twice')
而是等待文本更改。我想等待文字颜色改变。谢谢
这是我的按钮的代码
<Button onPress = {() => {this.setState({state : 1});}}>
<Text style = {style}>Button Text</Text>
</Button>
所以当这个按钮被按下时。状态设置为 1。在渲染中:
if(this.state.state === 1) style = style1
else style = style2;
但是从日志可以看出,render是在测试检查样式之后调用的。那么如何在检查字体颜色是否已更改之前等待渲染完成?
这里是测试代码
test('The button text style changes after press', () => {
const {getByText} = render(<Component/>);
fireEvent.press(getByText('button'));
expect(getByText('button')).toHaveStyle({
color : '#ffffff'
});
})
你可以试试
<Text style = {this.state.state === 1 ? style1 : style2}>Button Text</Text>
这将导致样式一直被定义。所以你不必等待 setState 完成。
编辑
您可以使用 setState 函数提供的回调来执行样式测试。
this.setState({
state : 1
} , () => {
//this is called only after the state is changed
//perform your test here
})
您似乎有一个自定义按钮,而不是本机按钮。我猜你的组件是这样的:
import React from "react";
import {Text, TouchableOpacity, View} from "react-native";
const Button = ({pressHandler, children}) => (
<TouchableOpacity onPress={pressHandler}>
{children}
</TouchableOpacity>
);
const ColorChangingButton = ({text}) => {
const [color, setColor] = React.useState("red");
const toggleColor = () => setTimeout(() =>
setColor(color === "green" ? "red" : "green"), 1000
);
return (
<Button pressHandler={toggleColor}>
<Text style={{color}}>{text}</Text>
</Button>
);
};
export default ColorChangingButton;
如果是这样,您可以按照 :
所述使用 waitFor
进行测试
import React from "react";
import {
fireEvent,
render,
waitFor,
} from "@testing-library/react-native";
import ColorChangingButton from "../src/components/ColorChangingButton";
it("should change the button's text color", async () => {
const text = "foobar";
const {debug, queryByText} = render(<ColorChangingButton text={text} />);
fireEvent.press(queryByText(text));
await waitFor(() => {
expect(queryByText(text)).toHaveStyle({color: "green"});
});
});
对于具有 且不接受子项的本机按钮,而不是使用 title="foo"
,对 debug()
的调用表明它扩展为几个嵌套元素。您可以使用
const text = within(queryByRole("button")).queryByText(/./);
expect(text).toHaveStyle({color: "green"});
在 waitFor
回调中进入按钮的文本子项并等待它具有所需的颜色。
我为此 post 使用了相同的 packages/versions,如 React Testing Library: Test if Elements have been mapped/rendered 所示。
我有一个组件。它有一个按钮。按下按钮后,我将使用 setState 函数更改按钮文本(颜色)的样式。当我测试更改的组件时,测试失败,因为更改是异步发生的。我想做这里给出的事情 (https://testing-library.com/docs/dom-testing-library/api-async/)
const button = screen.getByRole('button', { name: 'Click Me' })
fireEvent.click(button)
await screen.findByText('Clicked once')
fireEvent.click(button)
await screen.findByText('Clicked twice')
而是等待文本更改。我想等待文字颜色改变。谢谢
这是我的按钮的代码
<Button onPress = {() => {this.setState({state : 1});}}>
<Text style = {style}>Button Text</Text>
</Button>
所以当这个按钮被按下时。状态设置为 1。在渲染中:
if(this.state.state === 1) style = style1
else style = style2;
但是从日志可以看出,render是在测试检查样式之后调用的。那么如何在检查字体颜色是否已更改之前等待渲染完成?
这里是测试代码
test('The button text style changes after press', () => {
const {getByText} = render(<Component/>);
fireEvent.press(getByText('button'));
expect(getByText('button')).toHaveStyle({
color : '#ffffff'
});
})
你可以试试
<Text style = {this.state.state === 1 ? style1 : style2}>Button Text</Text>
这将导致样式一直被定义。所以你不必等待 setState 完成。
编辑
您可以使用 setState 函数提供的回调来执行样式测试。
this.setState({
state : 1
} , () => {
//this is called only after the state is changed
//perform your test here
})
您似乎有一个自定义按钮,而不是本机按钮。我猜你的组件是这样的:
import React from "react";
import {Text, TouchableOpacity, View} from "react-native";
const Button = ({pressHandler, children}) => (
<TouchableOpacity onPress={pressHandler}>
{children}
</TouchableOpacity>
);
const ColorChangingButton = ({text}) => {
const [color, setColor] = React.useState("red");
const toggleColor = () => setTimeout(() =>
setColor(color === "green" ? "red" : "green"), 1000
);
return (
<Button pressHandler={toggleColor}>
<Text style={{color}}>{text}</Text>
</Button>
);
};
export default ColorChangingButton;
如果是这样,您可以按照
waitFor
进行测试
import React from "react";
import {
fireEvent,
render,
waitFor,
} from "@testing-library/react-native";
import ColorChangingButton from "../src/components/ColorChangingButton";
it("should change the button's text color", async () => {
const text = "foobar";
const {debug, queryByText} = render(<ColorChangingButton text={text} />);
fireEvent.press(queryByText(text));
await waitFor(() => {
expect(queryByText(text)).toHaveStyle({color: "green"});
});
});
对于具有 title="foo"
,对 debug()
的调用表明它扩展为几个嵌套元素。您可以使用
const text = within(queryByRole("button")).queryByText(/./);
expect(text).toHaveStyle({color: "green"});
在 waitFor
回调中进入按钮的文本子项并等待它具有所需的颜色。
我为此 post 使用了相同的 packages/versions,如 React Testing Library: Test if Elements have been mapped/rendered 所示。