javascript - Mocking fetch with jest.fn() in React - Stack Overflow

I'm wondering why I need to put fetch mock logic inside my test to make it work.Here is simple ex

I'm wondering why I need to put fetch mock logic inside my test to make it work.

Here is simple example:

Component to test with fetch inside useEffect and state update after response:

// Test.jsx

import React, {useEffect, useState} from 'react'

export const Test = () => {

    const [description, setDescription] = useState<string | null>(null)

    const fetchData = async () => {
        const response = await fetch('https://dummyendpoint/');
        const parsed = await response.json();
        const description = parsed.value;
        setDescription(description);
    }

    useEffect(() => {
        fetchData();
    }, [])

    return (
        <div data-testid="description">
            {description}
        </div>
    )
};

export default Test;

Test logic:

// Test.test.js

import React from 'react';
import {render, screen} from '@testing-library/react';

import Test from "./Test";

global.fetch = jest.fn(() => Promise.resolve({
    json: () => Promise.resolve({
        value: "Testing something!"
    })
}));

describe("Test", () => {

    it('Should have proper description after data fetch', async () => {

        // need to put mock logic here to make it work

        render(<Test/>);
        const description = await screen.findByTestId('description');
        expect(description.textContent).toBe("Testing something!");
    });
})

If I keep global.fetch mock at the top of my test file, I keep getting an error:

TypeError: Cannot read property 'json' of undefined
at const parsed = await response.json();

I'm wondering why I need to put fetch mock logic inside my test to make it work.

Here is simple example:

Component to test with fetch inside useEffect and state update after response:

// Test.jsx

import React, {useEffect, useState} from 'react'

export const Test = () => {

    const [description, setDescription] = useState<string | null>(null)

    const fetchData = async () => {
        const response = await fetch('https://dummyendpoint/');
        const parsed = await response.json();
        const description = parsed.value;
        setDescription(description);
    }

    useEffect(() => {
        fetchData();
    }, [])

    return (
        <div data-testid="description">
            {description}
        </div>
    )
};

export default Test;

Test logic:

// Test.test.js

import React from 'react';
import {render, screen} from '@testing-library/react';

import Test from "./Test";

global.fetch = jest.fn(() => Promise.resolve({
    json: () => Promise.resolve({
        value: "Testing something!"
    })
}));

describe("Test", () => {

    it('Should have proper description after data fetch', async () => {

        // need to put mock logic here to make it work

        render(<Test/>);
        const description = await screen.findByTestId('description');
        expect(description.textContent).toBe("Testing something!");
    });
})

If I keep global.fetch mock at the top of my test file, I keep getting an error:

TypeError: Cannot read property 'json' of undefined
at const parsed = await response.json();
Share Improve this question edited Jan 28, 2021 at 23:38 Knight asked Jan 28, 2021 at 23:33 KnightKnight 5732 gold badges12 silver badges27 bronze badges
Add a ment  | 

1 Answer 1

Reset to default 5

It's really strange that it does not work as it is.

But I was able to fix it by moving the setup into beforeEach block (I assume beforeAll would also work).

It is a mon pattern to backup global variable value, override it for tests and restore it back.

import React from 'react';
import { render, screen } from '@testing-library/react';

import Test from "./Test";



describe("Test", () => {
    let originalFetch;

    beforeEach(() => {
        originalFetch = global.fetch;
        global.fetch = jest.fn(() => Promise.resolve({
            json: () => Promise.resolve({
                value: "Testing something!"
            })
        }));
    });

    afterEach(() => {
        global.fetch = originalFetch;
    });

    it('Should have proper description after data fetch', async () => {

        // need to put mock logic here to make it work

        render(<Test />);
        const description = await screen.findByTestId('description');
        expect(description.textContent).toBe("Testing something!");
    });
});

发布者:admin,转转请注明出处:http://www.yc00.com/questions/1744142573a4560271.html

相关推荐

  • javascript - Mocking fetch with jest.fn() in React - Stack Overflow

    I'm wondering why I need to put fetch mock logic inside my test to make it work.Here is simple ex

    8天前
    30

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信