-
-
Save rafaelrozon/ed86efbea53094726e162dc05882cddc to your computer and use it in GitHub Desktop.
import React from 'react'; | |
import { storiesOf } from '@storybook/react'; | |
// 1. import axios and MockAdapter | |
import axios from 'axios'; | |
import MockAdapter from 'axios-mock-adapter'; | |
// 2. create the mock | |
const mock = new MockAdapter(axios); | |
// 2.1 the api request to be intercepted has to match exactly | |
const API_REQUEST = 'https://swapi.co/api/planets/1'; | |
// 3. your component | |
class Test extends React.Component { | |
constructor(props) { | |
super(props); | |
this.state = { data: {} }; | |
} | |
componentDidMount() { | |
const that = this; | |
axios.get(API_REQUEST). | |
then(function(response) { | |
that.setState({ data: response.data }) | |
}); | |
} | |
render() { | |
return ( | |
<div> | |
Response is <pre>{JSON.stringify(this.state.data, null, ' ')}</pre> | |
</div> | |
); | |
} | |
} | |
storiesOf('Mocking Api responses with Axios and axios-mock-adapter', module) | |
.add('Test', () => { | |
// 4. create the mock inside the story | |
// if this is outside it'll mess up with other axios instances/requests | |
mock.onGet(API_REQUEST).reply(200, { test: 'some mock data' }); | |
return <Test /> | |
}); |
Found this answer while I was trying to mock axios inside of my stories, ran into an issue when I added multiple stores (that 404 error that @husni1992 mentions) it was basically an issue with the mocks colliding.
I ended working around it creating a helper component, which does the mocking.
Helper component:
import { useEffect } from 'react';
import MockAdapter from 'axios-mock-adapter';
import { api } from '../../services'; // This is an AxiosInstance
interface IProps {
children: any;
mock: (adapter: MockAdapter) => void;
}
const apiMock = new MockAdapter(api);
const AxiosMock = ({ children, mock }: IProps) => {
useEffect(() => {
mock(apiMock);
return () => {
apiMock.reset();
};
});
return children;
};
export default AxiosMock;
Usage in stories:
export const Default = () => {
const mock = (apiMock: MockAdapter) => {
apiMock.onGet('/api/meetings/1').reply(200, {
id: 1,
title: 'A Meeting',
});
};
return (
<AxiosMock mock={mock}>
<Meeting />
</AxiosMock>
);
};
I'm using Storybooks CSF
Initially I used example above and got same erors.
Moved const mock = new MockAdapter(axios);
inside story and error is gone.
Be aware that if you use your own Axios instance you should mock that instance, not the imported one
const axios = require('axios');
const axiosInstance = axios.create({
timeout: 30000
});
const mock = new MockAdapter(axiosInstance);
Initially I used example above and got same erors. Moved
const mock = new MockAdapter(axios);
inside story and error is gone.
I did this in all my stories and fixed my problem.
Many thanks to @ignaciojcano for your solution.
I would like to share my modified version that avoids the mock being always active in other stories.
With this approach you don't have to move const mock = new MockAdapter(axios);
inside the stories as noted by @laurentiu1981.
import MockAdapter from 'axios-mock-adapter'
import { ReactElement, ReactNode, useEffect, useRef } from 'react'
import axios from 'axios'
type AxiosMockProps = {
children: ReactNode
mock: (adapter: MockAdapter) => void
}
export function AxiosForBffMock({
children,
mock,
}: AxiosMockProps): ReactElement {
const mockAdapter = useRef(new MockAdapter(axios)).current
mock(mockAdapter)
useEffect(() => {
return () => {
mockAdapter.restore()
}
}, [mockAdapter])
return <>{children}</>
}
This comes when I tried to do the above. Any idea?
utils.js:117 Uncaught (in promise) Error: Request failed with status code 404
at createErrorResponse (utils.js:117)
at Object.settle (utils.js:97)
at handleRequest (handle_request.js:78)
at index.js:18
at new Promise ()
at MockAdapter. (index.js:17)
at dispatchRequest (dispatchRequest.js:59)