Рассмотрим следующий код:
class Dashboard extends Component {
state = {
fileName: "",
group: "",
country: "",
error: ""
};
onFormSubmit = async e => {
e.preventDefault();
const { group, country } = e.target;
try {
await axios.post("/api/dashboard", {
name: group.value,
country: country.value,
image: this.state.fileName
});
} catch (error) {
console.info(error.response.data.message);
this.setState({ error: error.response.data.message });
}
};
render() {
return (
<div>
<form onSubmit = {this.onFormSubmit}>
<input
type = "text"
onChange = {this.onGroupChange}
name = "group"
placeholder = "Group Name"
value = {this.state.group}
/>
{this.state.error}
<input
type = "text"
onChange = {this.onCountryChange}
name = "country"
placeholder = "Country"
value = {this.state.country}
/>
<ImageUpload
fileName = {this.state.fileName}
onFileNameChange = {this.onFileNameChange}
/>
<button type = "submit">Add Group</button>
</form>
</div>
);
}
}
Я пытаюсь проверить, что состояние error
установлено на соответствующее значение при сбое почтового запроса. Вот тест на данный момент:
it("should set error state when dashboard api returns error", async () => {
const errorMsg = "Group already exist";
moxios.stubRequest("/api/dashboard", {
status: 400,
response: {
message: errorMsg
}
});
const event = {
preventDefault: () => {},
target: {
group: "",
country: ""
}
};
const wrapper = shallow(<Dashboard />);
await wrapper.find("form").simulate("submit", event);
console.info(wrapper.state("error").value);
expect(wrapper.state("error")).toBe(errorMsg);
});
@curlyBraces Ага
Поскольку метод onformSubmit
- это async
, вы можете использовать несколько подходов:
1 Дождитесь асинхронного метода напрямую:
it(
'should set error state when dashboard api returns error',
async () => {
const wrapper = shallow(<Dashboard />);
await wrapper.instance().onFormSubmit(event);
expect(wrapper.state('error')).toBe(errorMsg);
}
);
и отдельно проверьте, что метод onFormSubmit
был вызван при событии submit
2 Использовать тайм-аут с возвратом Promise
:
it(
'should set error state when dashboard api returns error',
() => {
const wrapper = shallow(<Dashboard />);
wrapper.find("form").simulate("submit", event);
return new Promise(resolve => setTimeout(resolve, 1)).then(() => {
expect(wrapper.state('error')).toBe(errorMsg);
});
},
1000
);
3 await поставить галочку перед проверкой:
function tick() {
return new Promise(resolve => {
setTimeout(resolve, 1);
});
}
...
it('should set error state when dashboard api returns error', async () => {
const wrapper = shallow(<Dashboard />);
wrapper.find('form').simulate('submit', event);
await tick();
expect(wrapper.state('error')).toBe(errorMsg);
});
4 Использовать обратный вызов done
:
it('should set error state when dashboard api returns error', done => {
const wrapper = shallow(<Dashboard />);
wrapper.find('form').simulate('submit', event);
setImmediate(() => {
expect(wrapper.state('error')).toBe(errorMsg);
done();
});
});
Тест проходит, что бы ни случилось. Ни один из них не работает. Можете ли вы предоставить полный код?
Ваш первый подход полностью похож на мой
@UnityHour Что вы имеете в виду под passing
? Разве это не должно пройти? Вот код тестового файла: pastebin.com/y7gRk8mk. Обратите внимание, что я убрал константы из метода it
, просто для того, чтобы показать разницу подходов.
Мой первый подход - ожидание асинхронного метода, а не результата вызова события.
@UnityHour добавил два других подхода, а также обновил pastebin. Все они хорошо работают.
Вы пробовали
wrapper.update()
до выражения ожидания?