Mocking Axios with axios-mock-adapter

We are going to move to the project we created in Chapter 9Interacting with Restful APIs. We are going to add a test that verifies the posts are rendered on the page correctly. We'll mock the JSONPlaceholder REST API so we are in control of the data that is returned, and so that our test will execute nicely and quickly:

  1. First, we need to install the axios-mock-adapter package as a development dependency:
npm install axios-mock-adapter --save-dev
  1. We are also going to install react-testing-library:
npm install react-testing-library --save-dev
  1. The project already has a test file, App.test.tsx, which includes a basic test on the App component. We'll remove the test, but leave the imports, as we'll need these.
  2. In addition, we are going to import some functions from react-testing-libraryaxios and a MockAdapter class that we'll use to mock the REST API calls:
import { render, cleanup, waitForElement } from "react-testing-library";
import axios from "axios";
import MockAdapter from "axios-mock-adapter";
  1. Let's add the usual cleanup line that will execute after each test:
afterEach(cleanup);
  1. We'll create our test with an appropriate description, and place it under an App group:
describe("App", () => {
test("When page loads, posts are rendered", async () => {

// TODO - render the app component with a mock API and check that the posts in the rendered list are as expected
      });
});

Note that the arrow function is marked with the async keyword. This is because we'll eventually make an asynchronous call in our test.

  1. Our first job in our test is to mock the REST API call using the MockAdapter class:
test("When page loads, posts are rendered", async () => {
const mock = new MockAdapter(axios);
mock.onGet("https://jsonplaceholder.typicode.com/posts").reply(200, [
{
userId: 1,
id: 1,
title: "title test 1",
body: "body test 1"
},
{
userId: 1,
id: 2,
title: "title test 2",
body: "body test 2"
}
]);
});

We use the onGet method to define the response HTTP status code and body we want when the URL to get the posts is called. So, the call to the REST API should return two posts containing our test data.

  1. We need to check that the posts are rendered correctly. In order to do this, we are going to add a data-testid attribute to the unordered posts list in App.tsx. We are also only going to render this when we have data:
{this.state.posts.length > 0 && (
<ul className="posts" data-testid="posts">
...
</ul>
)}
  1. Moving back to our test, we can now render the component and destructure the getByTestId function:
mock.onGet("https://jsonplaceholder.typicode.com/posts").reply(...);
const { getByTestId } = render(<App />);
  1. We need to check that the rendered posts are correct, but this is tricky, because these are rendered asynchronously. We need to wait for the posts list to be added to the DOM before doing our checks. We can do this using the waitForElement function from react-testing-library:
const { getByTestId } = render(<App />);
const postsList: any = await waitForElement(() => getByTestId("posts"));

The waitForElement function takes in an arrow function as a parameter, which in turn returns the element we are waiting for. We use the getByTestId function to get the posts list, which finds it using its data-testid attribute.

  1. We can then use a snapshot test to check that the content in the posts list is correct:
const postsList: any = await waitForElement(() => getByTestId("posts"));
expect(postsList).toMatchSnapshot();
  1. Before our test can execute successfully, we need to make a change in tsconfig.json so that the TypeScript compiler knows that we are using async and await:
{
"compilerOptions": {
"target": "es5",
"lib": ["dom", "es2015"],
...
},
"include": ["src"]
}

When the test executes, the snapshot is created. If we inspect the snapshot, it will contain the two list items containing data that we told the REST API to return.

We've learned about some great features in Jest and react-testing-library that help us write maintainable tests on pure functions and React components.

How can we tell what bits of our app are covered by unit tests, thoughand, more importantly, what bits are uncovered? We'll find out in the next section.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.217.254.118