-
-
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)