dimanche 1 novembre 2020

Cannot mock axios service call within a jest test for a React Typescript component

I have a react frontend with a spring boot service that is my backend. Then I have a simple UsersList component:

import React from "react";
import "../../App.css";
import {IUser} from "../../model/interfaces.model";
import axios from "axios"

export class UsersListState {
    constructor(public readonly users: IUser[], public readonly loading: boolean) {
    }
}

export default class UserList extends React.Component<{}, UsersListState> {
    constructor(props) {
        super(props);
        this.state = new UsersListState([], true);
    }

    componentDidMount() {
        axios.get("/api/users")
            .then((res) => {
                console.log(res.data);
                this.setState(new UsersListState(res.data, false));
            })
            .catch((error) => {
                console.log("Could not load users: ", error);
                this.setState(new UsersListState([], false));
            });
    }

    render() {
        if (this.state.loading) {
            return (
                <div data-testid="loading">
                    <h4>Loading...</h4>
                </div>
            );
        } else {
            if (!Array.isArray(this.state.users) || !this.state.users.length) {
                return (
                    <div data-testid="no-users">
                        <h4>No users found matching your request.</h4>
                    </div>
                );
            } else {
                return (
                    <div data-testid="users">
                        {this.state.users.map((user) => (
                            <div key={user.id}>
                                {user.name}, {user.status}
                            </div>
                        ))}
                    </div>
                );
            }
        }
    }
}

My IUser model:

export interface IUser {
    id: string;
    name: string;
    status: string;
}

Here is my simple test UserList.test.ts:

import React from "react";
import "@testing-library/jest-dom/extend-expect";
import {cleanup, render} from "@testing-library/react";
import renderer from "react-test-renderer";
import UserList from "../UserList";

beforeEach(() => {
    jest.resetModules();
    jest.clearAllMocks();
});

afterEach(cleanup);

test("renders list of users from backend", () => {
    const {getByTestId} = render(<UserList/>);
    // this fails, as it renders "loading" testid instead
    expect(getByTestId("users")).toHaveTextContent("John Doe");
});

test("matches snapshot", () => {
    const tree = renderer.create(<UserList/>).toJSON();
    expect(tree).toMatchSnapshot();
});

And last but not least, I have an axios.js manual mock in the mocks directory:

module.exports = {
    get: jest.fn((url) => {
        const users = [
            {
                id: "6bd50444-14e1-4d2d-bca3-221318fad8a7",
                name: "John Doe",
                status: "available",
            }
        ];

        if (url === '/api/users') {
            return Promise.resolve({
                data: users
            });
        }
    }),
    create: jest.fn(function () {
        return this;
    })
};

So my test fails, as it renders "loading" test id. And I guess that's because my axios mock is not recognised? Can you spot what am I doing wrong?

Aucun commentaire:

Enregistrer un commentaire