reactjs - 如何使用反应测试库模拟将道具传递给子组件的父组件
问题描述
**如果传递给子组件的道具基于父组件中动态发生的状态更改,如何检查父组件中的动态状态更改并使用反应测试库编写测试用例。有人可以帮我弄这个吗?
应用程序.js
import React, { Component } from 'react';
import './App.css';
import TextArea from './components/TextArea/TextArea';
class App extends Component {
constructor() {
super();
this.state = {
textAreaParams: {},
};
}
componentDidMount() {
this.setDefaultTextAreaMessage();
}
setDefaultTextAreaMessage = () => {
this.setState({
textAreaParams: { message: 'Hello' },
});
};
render() {
const { textAreaParams } = this.state;
return (
<div className="App">
{Object.keys(textAreaParams).length > 0 ? (
<TextArea params={textAreaParams} />
) : null}
</div>
);
}
}
export default App;
文本区域.js
import { Component } from 'react';
class TextArea extends Component {
constructor(props) {
super(props);
this.state = {
message: this.props.params.message,
};
}
render() {
return (
<div>
<textarea
rows="4"
cols="50"
value={this.state.message ? this.state.message : ''}
placeholder="test"
onChange={() => {}}
>
{this.state.message}
</textarea>
</div>
);
}
}
export default TextArea;
应用程序.test.js
import App from './App';
import { cleanup, render } from '@testing-library/react';
describe('Rendering the App component and passing props to text area', () => {
afterEach(cleanup);
it('render the App component and check for the TextArea component', async () => {
const props = { textAreaParams: { message: 'save' } };
const { getByPlaceholderText } = render(<App {...props} />);
const textAreaParams = getByPlaceholderText('test');
expect(textAreaParams).toHaveTextContent('save');
});
});
解决方案
我们需要将onChange
处理程序属性从 App 组件传递给 TextArea,然后 TextArea 组件将在文本区域发生更改时调用该处理程序。
updateTextAreaMessage = (messageInTextArea) => {
this.setState({
textAreaParams: { message: messageInTextArea}
})
}
在上面的代码中,messageInTextArea
是一个字符串值,当我们改变TextArea中的文本时,当updateTextAreaMessage
在TextArea组件中以相同的字符串值作为参数调用时,它会更新App组件中的状态。
全面实施:
应用程序.js:
import React, { Component } from "react";
import './App.css';
import TextArea from './components/TextArea/TextArea';
class Main extends Component {
constructor() {
super();
this.state = {
textAreaParams: { message: "hello" } // we can provide default value here
};
}
updateTextAreaMessage = (messageInTextArea) => {
this.setState({
textAreaParams: { message: messageInTextArea }
});
};
render() {
const { textAreaParams } = this.state;
return (
<div className="App">
{Object.keys(textAreaParams).length > 0 ? (
<TextArea
params={textAreaParams}
onUpdate={this.updateTextAreaMessage}
/>
) : null}
<p aria-label="text area message">{textAreaParams.message}</p>
</div>
);
}
}
export default Main;
文本区域.js:
import { Component } from "react";
class TextArea extends Component {
render() {
return (
<div>
<textarea
rows="4"
cols="50"
value={this.props.params.message ? this.props.params.message : ""}
placeholder="test"
onChange={(event) => this.props.onUpdate(event.target.value)}
>
{this.props.params.message}
</textarea>
</div>
);
}
}
export default TextArea;
现在,我们将为 App.js 添加测试。但问题是在这里测试什么?答案是我们将在 TextArea 组件的文本发生更改时添加状态是否更新的测试。
import { render } from "@testing-library/react";
import App from "./App";
import TextArea from './components/TextArea/TextArea';
describe("Rendering the App component and passing props to text area", () => {
it("should render the App component with default message in TextArea", () => {
const { getByPlaceholderText } = render(<Main />);
const textAreaParams = getByPlaceholderText("test");
expect(textAreaParams).toHaveTextContent(/hello/i);
});
it("should update the text area when we type something", () => {
const { getByPlaceholderText, getByLabelText } = render(<Main />);
userEvent.type(getByPlaceholderText("test"), "Anything");
expect(getByLabelText(/text area message/i)).toHaveTextContent(/anything/i);
});
});
describe("Rendering the Text Area component", () => {
it("should render the TextArea component and calls onChange handlers when we type something", () => {
const mockOnChangeHandler = jest.fn();
const mockParams = { message: "save" };
const { getByPlaceholderText } = render(
<TextArea params={mockParams} onUpdate={mockOnChangeHandler} />
);
const inputTextArea = getByPlaceholderText("test");
expect(inputTextArea).toHaveTextContent(/save/i);
userEvent.type(inputTextArea, "Anything");
expect(mockOnChangeHandler).toHaveBeenCalled();
});
});
推荐阅读
- javascript - 使用循环的 REACT 状态更新会覆盖以前的值
- c# - 如何使用 json 内容反序列化 json 属性
- python - 循环计算嵌套的 JSON 对象
- keyboard - ` 是什么,为什么它用于显示代码?
- swift - 收到 didReceiveResponse 连接错误
- python - 使用 imshow 的 Matplotlib 子图不共享相同的像素大小。图像不能保持一致的缩放比例
- java - java.lang.ExceptionInInitializerError 与 Java-16 | jlClassFormatError 可访问:模块 java.base 不会“打开 java.lang”到未命名的模块
- python - 在分布python中找到与y对应的x
- tinymce - 更改 Tiny MCE 帐户所有者
- python - 将数据帧写入 SQL 的函数