24/04/19
Suppose we want a "Users" component for fetching and displaying a list of users.
A naive implementation could use async / await in componentDidMount (although it’s a bad idea).
That means when laying down our test we can await on componentDidMount.
Here’s our test’s skeleton:
import React from "react";
import { create } from "react-test-renderer";
import Users from "../Users";
describe("Users component", () => {
it("shows a list of users", async () => {
const component = create();
const instance = component.getInstance();
await instance.componentDidMount();
//
});
});
You should be already familiar with create and getInstance from react-test-renderer.
Notice also how you can use async / await in Jest.
Also worth noting in the above example: I’m calling componentDidMount on the testing instance.
Now if I run npm test the above test fails because I haven’t created the component yet.
Better we make a minimal implementation for it!
It could be a stateful component which gets data from an remote API with Axios, and then displays such data to our users:
import React, { Component } from "react";
import axios from "axios";
export default class Users extends Component {
constructor(props) {
super(props);
this.state = { data: [] };
this.handleGet = this.handleGet.bind(this);
}
handleGet(response) {
this.setState(this.stateUpdater(response));
}
stateUpdater(response) {
return { data: response.data };
}
async componentDidMount() {
const response = await axios.get(
"https://jsonplaceholder.typicode.com/users"
);
this.handleGet(response);
}
render() {
return (
<ul>
{this.state.data.map(user => (
<li key={user.name}>{user.name}</li>
))}
</ul>
);
}
}
Nothing new uh?
I couldn’t resist using async/await on componentDidMount but let’s be clear: it is bad practice. You should always move asynchronous logic out of React components.
Anyway for this example it’s ok, we won’t do any harm.
I must confess I can’t resist to console.log too.
Are you ok if I snitch inside the state of my testing instance?
TODO
Accelerate development with an integration API.
TODO