How to unit test Promise catch() method behavior with async/await in Jest?

Viewed 12699

Say I have this simple React component:

class Greeting extends React.Component {
    constructor() {
        fetch("https://api.domain.com/getName")
            .then((response) => {
                return response.text();
            })
            .then((name) => {
                this.setState({
                    name: name
                });
            })
            .catch(() => {
                this.setState({
                    name: "<unknown>"
                });
            });
    }

    render() {
        return <h1>Hello, {this.state.name}</h1>;
    }
}

Given the answers below and bit more of research on the subject, I've come up with this final solution to test the resolve() case:

test.only("greeting name is 'John Doe'", async () => {
    const fetchPromise = Promise.resolve({
        text: () => Promise.resolve("John Doe")
    });

    global.fetch = () => fetchPromise;

    const app = await shallow(<Application />);

    expect(app.state("name")).toEqual("John Doe");
});

Which is working fine. My problem is now testing the catch() case. The following didn't work as I expected it to work:

test.only("greeting name is 'John Doe'", async () => {
    const fetchPromise = Promise.reject(undefined);

    global.fetch = () => fetchPromise;

    const app = await shallow(<Application />);

    expect(app.state("name")).toEqual("<unknown>");
});

The assertion fails, name is empty:

expect(received).toEqual(expected)

Expected value to equal:
    "<unknown>"
Received:
    ""

    at tests/components/Application.spec.tsx:51:53
    at process._tickCallback (internal/process/next_tick.js:103:7)

What am I missing?

4 Answers

Recently, I have faced the same issue and ended up resolving it by following way (taking your code as an example)

test.only("greeting name is 'John Doe'", async () => {

const fetchPromise = Promise.resolve(undefined);

jest.spyOn(global, 'fetch').mockRejectedValueOnce(fetchPromise)

const app = await shallow(<Application />);

await fetchPromise;

expect(app.state("name")).toEqual("<unknown>");}); 
Related