Testing React

24/04/19

Testing React Components: mocking Axios with Jest

Let’s start with a test.

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

Quick integration testing with Json-Server

Accelerate development with an integration API.

TODO