#reactjs #jestjs #enzyme
#reactjs #jestjs #enzyme
Вопрос:
Я пытаюсь протестировать этот метод, который отвечает за редактирование, но могу использовать строки, которые заменяют старый заголовок и старое тело на новое название и тело.
Это находится в разделе IF. Ниже приведен код, который реализует редактирование:
onEditNote = event => {
const {
target: { value: id }
} = event;
const obj = {
title: this.state.title,
body: this.state.body
};
// clear the errors while submitting
this.setState({ titleError: "", bodyError: "" });
if (obj.title === "") {
this.setState({ titleError: "Title empty, please add title" });
} else if (obj.body === "") {
this.setState({ bodyError: "Body empty, please add body" });
} else if (obj.title.length > 20) {
this.setState({ titleError: "Title is too long." });
} else {
this.setState(state => {
const list = state.notesArray.map(item => {
if (item.id === id) {
// eslint-disable-next-line no-param-reassign
item.title = obj.title;
// eslint-disable-next-line no-param-reassign
item.body = obj.body;
}
return item;
});
localStorage.setItem("items", JSON.stringify(list));
// eslint-disable-next-line no-undef
$("#editModal").modal("close");
this.onSuccessToast("Noted edited successfully.");
return {
list,
title: "",
body: ""
};
});
}
};
Это строки в приведенном выше коде, которые не охвачены тестом, который я реализовал:
if (item.id === id) {
// eslint-disable-next-line no-param-reassign
item.title = obj.title;
// eslint-disable-next-line no-param-reassign
item.body = obj.body;
}
И ниже приведен мой тест, который я внедряю, который не охватывает оператор IF, но я вижу, что я его рассмотрел:
it("should edit a Note.", () => {
wrapper = shallow(<App />);
$.fn.modal = jest.fn();
wrapper.instance().onEditNote({ target: { value: "0" } });
wrapper.instance().setState({
title: "huxy 12",
body: "hey huxy this is not great.",
notesArray: [{ title: "hey", body: "its good", id: "0" }]
});
wrapper.instance().setState(state => {
state.notesArray.map(item => {
if (item.id === "0") {
// eslint-disable-next-line no-param-reassign
item.title = state.title;
// eslint-disable-next-line no-param-reassign
item.body = state.body;
}
return item;
});
});
});
Чего мне не хватает в моем тесте?
РЕДАКТИРОВАТЬ Это мой отредактированный тест с помощью Jest Matchers, не работает.
it('should edit a Note.', () => {
wrapper = shallow(<App />);
$.fn.modal = jest.fn();
wrapper.instance().onEditNote({ target: { value: '0' } });
wrapper.instance().setState({
title: 'huxy 12',
body: 'hey huxy this is not great.',
notesArray: [{ title: 'hey', body: 'its good', id: '0' }],
});
wrapper.instance().setState((state) => {
state.notesArray.map((item) => {
if (item.id === '0') {
// eslint-disable-next-line no-param-reassign
item.title = state.title;
expect(item.title).toBe(state.title);
expect(item.title).not.toBeNull();
// eslint-disable-next-line no-param-reassign
item.body = state.body;
}
return item;
});
});
wrapper.instance().onEditNote({ target: { value: 0 } });
});
Это полное состояние :
constructor(props) {
super(props, props, props);
this.state = {
notesArray: [],
id: '',
title: '',
body: '',
search: '',
titleDisplay: '',
bodyDisplay: '',
titleError: '',
bodyError: '',
};
this.onHandleSubmit = this.onHandleSubmit.bind(this);
this.onHandleChange = this.onHandleChange.bind(this);
}
Комментарии:
1. Какова цель этого теста? Он не содержит утверждений. Оно не охватывает ничего, не только cover
if
.2. Спасибо @estus, я отредактировал свой вопрос с помощью jest matchers , но все еще эта область не охвачена. Пожалуйста, направьте меня.
Ответ №1:
Утверждения не должны помещаться внутри setState
обратного вызова. setState
предполагается, что он вызывается в оболочке Enzyme, а не в экземпляре. Ветви следует тестировать одну за другой, в зависимости от состояния ветви.
Это должно быть что-то вроде:
wrapper = shallow(<App />);
// mock $(...).modal and localStorage.setItem
wrapper.setState({ title: '' });
wrapper.instance().onEditNote({ target: { value: '0' } });
expect(wrapper.state.titleError).toEqual({ title: '', titleError: ... );
wrapper = shallow(<App />);
// mock $(...).modal and localStorage.setItem
wrapper.setState({ title: '' });
wrapper.instance().onEditNote({ target: { value: '0' } });
expect(wrapper.state.titleError).toEqual({ body '', bodyError: ... );
// etc.
Обычно не следует издеваться над глобальными значениями путем присвоения, jest.fn()
поскольку это может помешать их очистке, $(...).modal
является jest.spy
предпочтительным способом издевательства.
localStorage.setItem
также необходимо высмеять.
Комментарии:
1. Привет, спасибо за ответ, но я имел дело с
notesArray[]
состоянием. Проверьте в разделе РЕДАКТИРОВАНИЯ моего вопроса, я включил состояние.2. Вы основывались на
titleError
иbodyError
, но значения, которые я менял, находятся в notesArray. Итак, этот список содержит объектыtitle
,id
иbody
. Поэтому, когда он заполнен, это может быть примерно так :[{id:'0',title:"helllo","body:"am good"}]
.3. но значения, которые я менял, находятся в notesArray — нет, это не так, проверьте свой код еще раз.
notesArray
изменяется только вelse
. Я начал с самого начала, тестируя по одному условию за раз. Вы можете добавить отсутствующие ключи состояния вtoEqual
или использоватьtoMatchObject
для assertb только ключи, которые изменены в onEditNote.
Ответ №2:
I enhanced the following code to test for
const regex = /[^a-zA-Z0-9.s-] /;
принимать символы через запятую и — и пробел
stringGenerator = (length) => {
let result = '';
const characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789?:"}{} ,~amp;^$.\||$3#@%amp;()';
const charactersLength = characters.length;
for (let i = 0; i < length; i = 1) {
result = characters.charAt(Math.floor(Math.random() * charactersLength));
}
return resu<
};
regex.test(stringGenerator(7))