Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

axios-mock-adapter breaks when used on axios.create() instance after first test #346

Open
MrAngry777 opened this issue Jul 27, 2022 · 5 comments

Comments

@MrAngry777
Copy link

MrAngry777 commented Jul 27, 2022

I am using axios-mock-adapter to test my components. The strange thing is that only a single test can be run successfully because the next one always breaks. Each test works fine if run individually.

Here is my setup.

 "axios-mock-adapter": "^1.21.1",
 "axios": "^0.27.2",
 "@testing-library/jest-dom": "^5.16.1",
 "react": "^17.0.2",
 "typescript": "^4.5.4",
 

util.ts

export const client = axios.create({
    baseURL: process.env.REACT_APP_API_URL ? process.env.REACT_APP_API_URL : "",
    timeout: 10000,
});

The exported client is used internally by all my components

component.test.tsx

import MockAdapter from "axios-mock-adapter";
import {apiUrls, client} from "utils";
import {DUMMY_RESPONSE} from "dummy/data";
import {render, screen, waitFor} from "@testing-library/react";
import {MemoryRouter} from "react-router-dom";
import MyComponent from "MyComponent";

describe('MyComponent', () => {
    let mockClient: MockAdapter;
    beforeAll(() => {
        mockClient = new MockAdapter(client);
    })
    afterEach(() => {
        mockClient.reset()

    })
    afterAll(()=>{
        mockClient.restore()
    })

    it('should fetch images and render them', async () => {
        mockClient.onGet(apiUrls.myURL).reply(200, DUMMY_RESPONSE)
        const spy = jest.spyOn(client, 'get')
        render(
            <MemoryRouter>
                <MyComponent handleSubmit={() => {
                }}/>
            </MemoryRouter>)
        await waitFor(() => expect(spy).toBeCalledWith(apiUrls.fetchSecurityImages))
        await waitFor(() => expect(spy).toBeCalledTimes(1))
        await waitFor(() => {
            DUMMY_RESPONSE.forEach((image) => {
                expect(screen.getByAltText(image.alt)).toBeDefined()
            })
        })
        spy.mockClear()
    });
    it('should show loader while fetching images', async () => {
        mockClient.onGet(apiUrls.myURL).reply(200, DUMMY_RESPONSE)
        const spy = jest.spyOn(client, 'get')
        render(
            <MemoryRouter>
                <MyComponent handleSubmit={() => {
                }}/>
            </MemoryRouter>)
        
        await waitFor(() => expect(spy).toBeCalledWith(apiUrls.myURL))
        await waitFor(() => expect(spy).toBeCalledTimes(1))
        await waitFor(() => {
            DUMMY_RESPONSE.forEach((image) => {
                expect(screen.getByAltText(image.alt)).toBeDefined()
            })
        })
        spy.mockClear()
    });
});

The second test (I mean the second that is run not the order they are defined) always breaks because of an error in the useEffect() hook which throws:

Cannot read properties of undefined (reading 'data')
TypeError: Cannot read properties of undefined (reading 'data')

And this is the function that breaks:

useEffect(() => {
        const fetchImages = async () => {
            try {
                const response = await client.get(apiUrls.fetchImages) // <--- here we get undefined
                setImages(response.data)
            } catch (e: any) {
                handleErrors(e)
            }
        }
        fetchImages()
    }, [])

BTW I am aware those tests look the same. That is exactly the point. Earlier there was a delay introduced in the second one but while debugging I changed them to pinpoint the problem but with no luck.

@sinner
Copy link

sinner commented Oct 28, 2022

I think I have the same issue.

@raohammad
Copy link

same issue

@murrayee
Copy link

murrayee commented Mar 6, 2023

same

@changwoolab
Copy link

Same issue

@changwoolab
Copy link

changwoolab commented May 8, 2023

In my case, after deleting jest.restoreAllMocks and jest.resetAllMocks in afterEach, it worked.
I think jest.resetAllMocks and jest.restoreAllMocks also resets axios mock, and in the test suite No-mocked axios instance is used.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants