Consider the following code :
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.log(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>
);
}
}
I am trying to test the error
state is set to appropriate value when post request fails. Here is the test so far:
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.log(wrapper.state("error").value);
expect(wrapper.state("error")).toBe(errorMsg);
});
As the method onformSubmit
is async
, you can go with several approaches there:
1 Await for an async method directly:
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);
}
);
and separately test that the method onFormSubmit
was called on submit
event
2 Use timeout with returning 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 tick before checking:
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 Use done
callback:
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();
});
});