#reactjs #unit-testing #jestjs #enzyme #mount
Вопрос:
У меня есть один родительский компонент people_form.js с тремя входными полями a. имя пользователя b. имя фамилии c. дата рождения
// people_form.js
import { fetch } from "request";
fetchDuplicateRecords() {
const {
first_name,
last_name,
date_of_birth,
} = this.state;
if (first_name amp;amp; last_name amp;amp; date_of_birth) {
const searchParams = {
first_name: first_name,
last_name: last_name,
date_of_birth: date_of_birth,
};
// url is fetched in other code.
fetch(url, searchParams)
.then(
(response) => {
this.setState({
duplicateRecords: response,
});
},
(err) => {
this.setState({
duplicateRecords: [],
});
}
)
} else {
this.setState({
duplicateRecords: [],
});
}
}
// few more functions in this file
render(){
const {
duplicateRecords,
} = this.state;
console.log('check',!_.isEmpty(duplicateRecords));
return (
<React.Fragment>
<form>
// other child components which are rendered.
{!_.isEmpty(duplicateRecords) amp;amp;
<DuplicateRecordsFinder
duplicateRecords={duplicateRecords}
onInputChange={this.handleInputChange}
closeDuplicateRecordList={this.handleDuplicateRecordsCloseEvent}
/>}
</form>
</React.Fragment>
)
}
В приведенном выше коде fetchDuplicateRecords выполняется при добавлении трех вышеупомянутых полей
. Ниже приводится request.js код файла.
// request.js
export function fetch(url, data = {}) {
return $.ajax({
url: url,
method: "GET",
dataType: "json",
contentType: "application/json",
data,
});
}
// duplicate_records_finder.js
export class DuplicateRecordsFinder extends Component {
initialState() {
return {
duplicateRecordsChunk: _.chunk(
this.props.duplicateRecords,
3
)
}
}
componentDidUpdate(props) {
if (this.props.duplicateRecords !== props.duplicateRecords) {
this.setState(this.initialState());
}
}
render() {
const { duplicateRecordsChunk } = this.state;
console.log("i am here");
console.log("duplicateRecordsChunk", duplicateRecordsChunk);
return (
<div
className="card card-profiles mb-4"
>
)
}
}
I am using Jest and Enzyme for unit testing.
- When we enter the first_name, last_name and date_of_birth, the
fetchDuplicateRecords function is triggered. - This makes an ajax call to the backend and set the state.
- This state change triggers people_form.js and DuplicateRecordsFinder component is displayed on UI.
- Using Jest and Enzyme, I am trying to create this scenario. Below is my unit test.
// people_form.test.js
import * as request from "request";
beforeEach(() => {
wrapper = mount(<PeopleForm/>)
});
test("it should display duplicate records when person already exists", () => {
// mock fetch (ajax)
request.fetch = jest.fn().mockReturnValueOnce(new Promise((resolve, reject) => { resolve(duplicateRecords); }))
const firstNameInput = wrapper.find("input[name='first_name']");
firstNameInput.simulate("change", { target: { value: "First", name: "first_name" } });
const lastNameInput = wrapper.find("input[name='last_name']");
lastNameInput.simulate("change", { target: { value: "Last", name: "last_name" } });
// enter date of birth value.
const dobInput = wrapper.find("input[name='date_of_birth']");
dobInput.simulate("change", { target: { value: "08-13-1990", name: "date_of_birth" } });
// wrapper.setState({ first_name: 'First', last_name: "Last", date_of_birth: "08-13-1990", showDuplicateRecords: true,
// duplicateRecords: duplicateRecords });
expect(wrapper.containsMatchingElement(<DuplicatePatientRecordsFinder />)).toEqual(true);
})
When I execute the above test this is the output
expect(received).toEqual(expected) // deep equality
Expected: true
Received: false
expect(wrapper.find(DuplicateRecordsFinder).length).toEqual(true);
console.log
check false
at PeopleForm.render (form/people_form.js:311:13)
console.log
check false
at PeopleForm.render (form/people_form.js:311:13)
console.log
check true
at PeopleForm.render (form/people_form.js:311:13)
console.log
i am here
at DuplicateRecordsFinder.render (form/duplicate_records_finder.js:75:13)
console.log
duplicateRecordsChunk [
// data here
]
В соответствии с выводом элемент управления достигает визуализации DuplicateRecordsFinder
компонента, но ожидаемая визуализация компонента DuplicateRecordsFinder является ложной, что означает, что дерево компонентов не обновляется.
Однако, если я явно задам first_name, last_name, date_of_birth в состоянии, это даст ожидаемый результат.
Я нашел связанную проблему на github.
Любая помощь или предложение будут высоко оценены