如何使用反应测试库模拟将道具传递给子组件的父组件
How to mock a parent component which passes props to child component using react testing library
**如果传递给子组件的props是基于父组件中动态发生的状态变化,如何检查父组件中的动态状态变化并使用react测试库编写测试用例零件。有人可以帮我解决这个问题吗?
App.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;
TextArea.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;
App.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
handler 属性从 App 组件传递给 TextArea,然后 TextArea 组件将在文本区域发生变化时调用该处理程序。
updateTextAreaMessage = (messageInTextArea) => {
this.setState({
textAreaParams: { message: messageInTextArea}
})
}
在上面的代码中,messageInTextArea
是一个字符串值,当我们改变TextArea中的文本时,当updateTextAreaMessage
以相同的字符串值作为参数在TextArea组件中调用时,它会更新 App 组件中的状态。
完全实施:
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;
TextArea.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();
});
});
**如果传递给子组件的props是基于父组件中动态发生的状态变化,如何检查父组件中的动态状态变化并使用react测试库编写测试用例零件。有人可以帮我解决这个问题吗?
App.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;
TextArea.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;
App.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
handler 属性从 App 组件传递给 TextArea,然后 TextArea 组件将在文本区域发生变化时调用该处理程序。
updateTextAreaMessage = (messageInTextArea) => {
this.setState({
textAreaParams: { message: messageInTextArea}
})
}
在上面的代码中,messageInTextArea
是一个字符串值,当我们改变TextArea中的文本时,当updateTextAreaMessage
以相同的字符串值作为参数在TextArea组件中调用时,它会更新 App 组件中的状态。
完全实施:
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;
TextArea.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();
});
});