blog.noob.pro

Very learning, much smart, so motivation

Testing in React

Because just clicking around is not good enough

Code without tests is broken by design

Without tests your users will be the beta testers.

Snapshot tests

One of the simplest ways to test a React component. Snapshot testing should be used to test the UI (avoid testing JavaScript code with this approach).

Snapshot testing example:

  1. Create a new file in a folder called tests, inside your project’s src folder.

  2. Jest will look there for new tests to run.

  3. Then in the test file you should import React, react-test-renderer, and the component you want to test.

  4. An example of a test:

   import React from "react";
   import { create } from "react-test-renderer";
   import FeatureComponent from "../FeatureComponent";
   describe("Feature component", () => {
     test("it matches the snapshot", () => {
       const component = create(<FeatureComponent />);
       expect(component.toJSON()).toMatchSnapshot(); // toMatchSnapshot is a method provided by Jest, it:
         // - Creates a snapshot if there isn't any
         // - Checks if the component matches the snapshot object
     });
   });

Breakdown of code:

  • react-test-renderer is a library for rending React components to pure JavaScript objects (create is a method that is used for “mounting” the component). create() creates an instance of the component that you can make assertions on. react-test-renderer doesn’t use the real DOM.

If your component changes frequently avoid snapshot testing. If you modify the component the test will fail.

Hands on react-test-renderer

  • Library for rending React components as pure JavaScript objects. We can also use it for assertion.

With TDD you write a test that fails before you do anything else.

When testing a stateful React component (the component has its own state) do not test the implementation, test from the user’s perspective (test what the user should see). Don’t test what the state properties equal, this is not testing from the user’s point of view.

A functional test or end-to-end test (same thing) is testing from the user’s point of view.

Use Cypress for functional testing, or you can do something like this (remember don’t test the state of the component, test what the user sees):

// Button.spec.js
import React from "react";
import { create } from "react-test-renderer";
import Button from "../Button";
describe("Button component", () => {
  test("it shows the expected text when clicked", () => {
    const component = create(<Button text="SUBSCRIBE TO BASIC" />);
    const rootInstance = component.root;
    const button = rootInstance.findByType("button");
    button.props.onClick();
    expect(button.props.children).toBe("PROCEED TO CHECKOUT");
  });
});

We can also enhance this test by simulating the button click.

Test doubles and mocks

Don’t call the actual API endpoint in your test, mock the JSON data that the API returns.

Axois with Jest

Note: Always move asynchronous logic out of React components.

import React from "react";
import { create } from "react-test-renderer";
import Users from "../Users";
import axios from "axios";
jest.mock("axios");
describe("Users component", () => {
  it("shows a list of users", async () => {
    const response = {
      data: [{ name: "Kevin Mitnick" }, { name: "Valentino Gagliardi" }]
    };
    axios.get.mockResolvedValue(response);
    const component = create(<Users />);
    const instance = component.getInstance();
    await instance.componentDidMount();
    const root = component.root;
    const listOfLi = root.findAll(element => element.type === "li");
    expect(listOfLi[0].props.children).toBe("Kevin Mitnick");
    expect(listOfLi[1].props.children).toBe("Valentino Gagliardi");
  });
});

The above example mocks an API call and tests what the user sees. However, if we were to call an incorrect API endpoint the test would still pass (since we didn’t test this in the above example).

Functional testing drives our development so lets stub out the API response.

Stubbing out responses with Cypress

img

Mocking: Replacing a real function with a fake one

Stubbing: out responses it means switching off the real API

Cypress is a Javascript End to End testing framework In contrast to Puppeteer, which is a library, Cypress gives you a solid platform for writing and automating UI tests. Without worrying too much about the rest.

Install Cypress

npm i cypress --save-dev

Scaffold Cypress’ directories with:

node_modules/.bin/cypress open

Cypress will create its own directories under ./cypress

In my case I start creating a new file named app_spec.js inside cypress/integration/. It will hold my first test.

A fixture is a piece of static data that can be used during your tests. Fixtures are used for faking JSON responses from a route. Moreover they are useful for defining users and models inside your testing environment.

Comments

Loading comments...