GithubHelp home page GithubHelp logo

jest-mock-axios's People

Contributors

belzee10 avatar cezarmanea avatar chris-thompson-bnsf avatar danawoodman avatar ddio avatar dependabot[bot] avatar epegzz avatar geekychristine avatar jonjaques avatar kingjan1999 avatar knee-cola avatar maadhattah avatar mcjlnrtwcz avatar moustacheful avatar niltonvasques avatar ntnyq avatar ogonkov avatar rubenduiveman avatar sirlisko avatar thiefmaster avatar vantanev avatar victorcorcos avatar webbushka avatar yarilchenko avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar

jest-mock-axios's Issues

Typings declaration file is missing

types path in package.json does not match any files. index.d.ts file is not present in current build under given path so typings do not work.

Mocking axios.CancelToken

I understand that jest-mock-axios provides axios cancel interfaces, but does anyone have any examples of how they have implemented this, specifically mocking axios.CancelToken?

Thanks.

Does not have axios.request just the helper methods..

I don't think this has axios.request() can you confirm?

I tried to proxy axios.request -> axios() which is similar, that did not work, and I tried writing a switch to call the axios methods similar to how axios does it, did not work either.

This lib is much closer to working for me than others, as it can be used to mock axios in other libs that import it.

mockAxios doesn't implement `isAxiosError`

Given that it's intended to be a drop-in replacement for axios, it would be useful to have this in the library (vs stubbing it in user code). Happy to PR a fix here if you're open to adding this.

finally() called to early

Due to fluffynuts/synchronous-promise#15 any .finally() blocks on production axios calls will be called before the call is completed by using axios.mockRequest() or axios.mockError() if synchronous-promise 2.0.9 is used. Increasing the dependency like such:

"dependencies": {
  "synchronous-promise": "^2.0.10"
}

should fix this issue though.

create mock missing from npm build?

I'm working on some code that uses axios with Jest for unit testing and ran into an issue using jest-mock-axios. The npm package doesn't appear to have the create functionality available. When using the library to mock axios I am seeing this error:

TypeError: _axios2.default.create is not a function

To get around this I cloned your repo and tried to do a build locally to compare files but the build appears to have issues (or maybe I have something weird going on locally).

This is the error I am seeing with the build:

ERROR in ./lib/mock-axios.ts
[tsl] ERROR in /Users/tnt3201/projects/jest-mock-axios/lib/mock-axios.ts(22,3)
      TS2322: Type 'Mock<this>' is not assignable to type 'MockAxios'.
  Property 'pending_promises' is missing in type 'Mock<this>'.
npm ERR! code ELIFECYCLE
npm ERR! errno 2
npm ERR! [email protected] build: `webpack -p`
npm ERR! Exit status 2
npm ERR! 
npm ERR! Failed at the [email protected] build script.

I did an npm install then npm run build and this was the resulting output. This error seems to be related to the line specifically for the mocked create method.

public create:MockAxios = jest.fn(() => this)

I removed the type and that seemed to fix the build, but I'm not familiar with TypeScript so I'm not sure what the "right" way to do this would be (keeping the type in place if possible).

public create = jest.fn(() => this)

Doing this fixes the create is not a function error and seems to fix the issue, at least for me. Just FYI if you want to fix/update the npm package so the create functionality is present.

mock axios using axios interceptors

I'm trying to use mockAxios for testing with axios interceptors.

image

image

When I created mockAxios:
export default {
get: jest.fn(() => Promise.resolve(data: {}))
}
All of my tests failed with the follow message: cannot read property response of undefined inside of axios interceptors. It happens because mock axios doesn't return response. It could just return a plain object. So how can I use axios interceptors with mockAxios for testing?
image

jest-mock-axios incompatible with CRA 4 / resetMocks: true

Hi!

We're using this library in a project built with Create React App, and have followed the async / await testing pattern outlined in #28.

I'm trying to upgrade us to CRA 4, but doing so is breaking all of these tests with Error: No request to respond to!. Bumping major CRA version bumps a load of sub-dependencies, so guessing one of these is the actual cause (jest seems most likely) - I'm happy to check other package versions before/after the upgrade if there are any in particular you think will be relevant!

We were using version 2.3.0 of this library, but can also reproduce the issue on the latest version (4.2.1). I've put together a SRE of three files to demonstrate what's happening.

Our axios instance, defined in axiosInstance.ts

import axios from 'axios'

export const axiosInstance = axios.create({
  baseURL: '/api',
  timeout: 20000,
  withCredentials: true,
  headers: { 'X-Csrf-Prevention': 'true' },
})

A fake API to test in sreApi.ts

import { AxiosResponse } from 'axios'
import { axiosInstance } from './axiosInstance'

export const callEndpoint = async (data: string): Promise<AxiosResponse> => {
  return axiosInstance.post('/endpoint', data)
}

The test that fails after the upgrade, but passes before in sreApi.test.ts

import { callEndpoint } from './sreApi'
import mockAxios from 'jest-mock-axios'

it('should call the correct endpoint', async () => {
  const promise = callEndpoint('some-data')
  mockAxios.mockResponse({ data: 'response' }) <-- blows up here
  const result = await promise

  expect(mockAxios.post).toHaveBeenCalledWith('/endpoint', 'some-data')
  expect(result.data).toBe('response')
})

In the above example, the mockResponse line blows up with:

Error: No request to respond to!
    at Function.mockResponse (/home/me/sre-package/node_modules/jest-mock-axios/lib/mock-axios.ts:170:15)
    at Object.<anonymous> (/home/me/sre-package/src/sre/sreApi.test.ts:6:13)
    at Promise.then.completed (/home/me/sre-package/node_modules/jest-circus/build/utils.js:276:28)
    at new Promise (<anonymous>)
    at callAsyncCircusFn (/home/me/sre-package/node_modules/jest-circus/build/utils.js:216:10)
    at _callCircusTest (/home/me/sre-package/node_modules/jest-circus/build/run.js:212:40)
    at processTicksAndRejections (internal/process/task_queues.js:85:5)
    at _runTest (/home/me/sre-package/node_modules/jest-circus/build/run.js:149:3)
    at _runTestsForDescribeBlock (/home/me/sre-package/node_modules/jest-circus/build/run.js:63:9)
    at run (/home/me/sre-package/node_modules/jest-circus/build/run.js:25:3)
    at runAndTransformResultsToJestFormat (/home/me/sre-package/node_modules/jest-circus/build/legacy-code-todo-rewrite/jestAdapterInit.js:176:21)

Interestingly, reordering the test like this still fails but does pass the call assertion, so mockAxios.post is definitely still being called:

it('should call the correct endpoint', async () => {
  const promise = callEndpoint('some-data')
  expect(mockAxios.post).toHaveBeenCalledWith('/endpoint', 'some-data')
  mockAxios.mockResponse({ data: 'response' }) <-- still blows up here
  const result = await promise

  expect(result.data).toBe('response')
})

Versions that work:

jest: 24.9.0
react-scripts: 3.4.4
axios: 0.18.1
jest-mock-axios: 4.2.1

Versions that don't work (after upgrade):

jest: 26.6.0
react-scripts: 4.0.1
axios: 0.18.1
jest-mock-axios: 4.2.1

Generator functions?

Does this library work with generator functions? And if so, can I get an example on how to write a test case for it?

Let's say the generator function is very basic, such as:

export function* testApi(url) {
  try {
    return yield axios.get(url);
  } catch(error) {
    console.log('ERROR:', error);
    throw error;
  }

Using with vue component tests

I am trying to use the package with a axion request on a vue component following the basic example but maybe I am not understanding the basics here, I can't get a then spy to have been called.

<!-- Component.vue -->
<input
  class="search-input form-control"
  id="field-text"
  type="text"
/>

<div class="search-results" v-if="searchResults">
    <div
        v-for="searchResult in searchResults"
        :key="searchResult.id"
        class="search-result"
    >
        {{ searchResult.country }}
    </div>
    <div
        v-if="searchResults.length === 0"
        class="no-results"
    >
        No result found
    </div>
</div>
<script>
onInput: _.debounce(function(event) {
    api.search(this.term).then(
        ({data}) => this.results = data
    )
}, 300)
</script>

Then the test which uses vue-testing-library is as follows

// Component.spec.js
it('renders properly', async (done) => {
    let catchFn = jest.fn(),
        thenFn = jest.fn();

    // using the component, which should make a server response
    let term = 'London';

    render(Component, {
            localVue,
            store: store,
        })
    }

   
    const input = screen.getByRole('textbox')
    await userEvent.type(input, term)
    await userEvent.click(document.body)

    // Set timeout is required since there is a debounce of 300ms on input field
    setTimeout((async () => {
        done()

        // since `post` method is a spy, we can check if the server request was correct
        // a) the correct method was used (post)
        // b) went to the correct web service URL ('/search')
        // c) if the payload was correct ('{term: term}')
        expect(mockAxios.post).toHaveBeenCalledWith('/search', {term: term });

        // simulating a server response
        let responseObj = {
            "data": [
                {
                    "id": 1,
                    "country": "Foo",
                },
                {
                    "id": 2,
                    "country": "Bar",
                },
            ]
        };
        mockAxios.mockResponse(responseObj);

        // checking the `then` spy has been called and if the
        expect(thenFn).toHaveBeenCalled();

        // catch should not have been called
        expect(catchFn).not.toHaveBeenCalled();

        // debug the output
        screen.debug();
    }), 400)
});

In the test the first assertion (expect(mockAxios.post).toHaveBeenCalledWith('/search', {term: term });) works as expected. It mocks the response as well but it fails on the expect(thenFn).toHaveBeenCalled(); showing there were 0 calls for thenFn.

I was also expecting the results on the this.results = data to be populated with the mocked response data and the template updated, just like when you get a response from an actual api endpoint would but it looks like that never happens. Am I missing something here?

No request to respond to! when used along with multiple async await

Thanks for your package. Love it !
But I seem to have an issue with it when using it along with async-await functions.
Test Code looks like
test("authenticate", async () => { let promiseObj = authenticate(email, password).then((msg) => {}).catch(catchFn) // simulating a server response let responseObj = { data: ["centralpet"] }; mockAxios.mockResponse(responseObj); expect(catchFn).not.toHaveBeenCalled(); return promiseObj; })

Now my source code - authenticate implementation looks like

authenticate = async (email, password) => { //This called a chrome async method. Not axios. let client = await utils.updateClientDetailsFromEmail(email); // This calls the axios methods. let status = await httpService.makeNetworkCall(requestObject); return status; }

Since inside the authenticate I am using await, the function gets paused before calling axios.
Meanwhile, the calling function continues execution and goes to mockResponse.
There mockAxios finds that no axios functions are in Queue so it throws No request to respond to! error.
If I await the authenticate call the mockResponse never gets executed so axios times out.

Can you check this issue or is there any workaround or config I am missing to avoid queuing of axios calls?

.mockError throwing error because axios call not yet added to mock

I am testing an async method using axios, and am finding that the mockError is throwing an error because the request has not yet been added to the mock. I followed an example for using the library with an async method but still no luck. Any adivce is appreicated:

Secure.ts

    async loadFromCode(code: string, state: string | undefined) {

        const storage = await this.getStorage()
        if (!storage) {
            throw new Error('Nothing in storage')
        }
        const data = new FormData();
        data.set(grantTypeKey, 'authorization_code')
        data.set(codeKey, code)
        data.set(codeVerifierKey, storage.pkce.verifier)

        const res = await axios({
            method: 'POST',
            url: this.params.issuer + '/oauth/token',
            data: data,
            adapter: require('axios/lib/adapters/xhr'),
            headers: { 'Content-Type': 'multipart/form-data' }
        })

        const resp: TokenResponse = JSON.parse(res.data)

        this.authentication = {
            accessToken: resp.access_token,
            idToken: resp.id_token,
            refreshToken: resp.refresh_token,
            expiresIn: resp.expires_in,
        }
    }

Secure.test.ts

        describe('return with valid code and server error', () => {
            it('Handles server error', async () => {
                query = `?code=${code}`
                sessionStorage.__STORE__[storageKey] = JSON.stringify({
                    pkce: {
                        challenge: challenge,
                        verifier: verifier
                    },
                    state: state,
                    nonce: nonce
                })
                const err = new Error('Host cannot be reached')
                try {
                    const req = unit.loadFromCode('test', 'test')
                    mockAxios.mockError(err)
                    await req
                    fail('Expected exception')
                } catch (e) {
                    expect(e).toEqual(err)
                }
                const data = new FormData();
                data.set('grant_type', 'authorization_code')
                data.set('code', code)
                data.set('code_verifier', verifier)
                expect(mockAxios).toHaveBeenCalledWith({
                    method: 'POST',
                    url: issuer + '/oauth/token',
                    data: data,
                    headers: { 'Content-Type': 'multipart/form-data' }
                });

            })
        });

Result:

expect(received).toEqual(expected) // deep equality

    Expected: [Error: Host cannot be reached]
    Received: [Error: No request to respond to!]

      144 |                     fail('Expected exception')
      145 |                 } catch (e) {
    > 146 |                     expect(e).toEqual(err)
          |                               ^
      147 |                 }
      148 |                 const data = new FormData();
      149 |                 data.set('grant_type', 'authorization_code')

      at src/__tests__/Secure.test.ts:146:31
      at step (src/__tests__/Secure.test.ts:33:23)
      at Object.next (src/__tests__/Secure.test.ts:14:53)
      at src/__tests__/Secure.test.ts:8:71
      at Object.<anonymous>.__awaiter (src/__tests__/Secure.test.ts:4:12)
      at Object.<anonymous> (src/__tests__/Secure.test.ts:129:40)

Question: Does jest.mock('axios') get called automatically?

Not an issue, just a question.

Before using this wonderful library I would always have to use jest.mock('axios') at the top of my test to ensure that real api calls were not being made. I was wondering if this is now called by default inside your library?

Question: Why use this instead of the built in mock that comes with Jest?

Hey,

I have been mocking my axios method via Jest for a while now but came across this package and I've wondered what it does for you that the built in Jest mocking doesn't?

In my React component I simply have:

jest.mock('axios');

const fetchMockPosts = () => {
  axiosMock.get.mockResolvedValueOnce({
      data: {
        posts: ['post1', 'post2']
      }
  });
};

test('should find and display posts', async () => {
  // Setup
  fetchMockPosts();
  render(<Page />);

  // Wait for loading text to disappear so we know the mocked posts have been fetched and displayed
  await waitForElementToBeRemoved(() => screen.queryByText('Loading posts'));

  // Find the post title
  expect(screen.getByText('post1')).toBeInTheDocument();
});

UnhandledPromiseRejectionWarning: TypeError: Caught error after test environment was torn down

Get Error when test faild case in post request image for Error when run test

Using Reactjs framework version 16

axios-hooks for api requests

react-testing-library for test

UnhandledPromiseRejectionWarning: TypeError: Caught error after test
environment was torn down

Cannot read property 'nodeType' of null (node:171)
UnhandledPromiseRejectionWarning: Unhandled promise rejection. This
error originated either by throwing inside of an async function
without a catch block, or by rejecting a promise which was not handled
with .catch(). (rejection id: 4)

test code

test('If user enters an invalid email or password', async () => {
  const { getByText, getByLabelText, getByTestId } = render(
    <Provider store={mockStore}>
      <Login />
    </Provider>
  )
  fireEvent.change(getByLabelText('Email'), {
    target: { value: '[email protected]' }
  })
  fireEvent.change(getByLabelText('Password'), {
    target: { value: 'password' }
  })

  getByText('Sign in').click()
  await waitForDomChange()
  await act(async () => {
    try {
      await MockAxios.mockError({
        code: 400,
        data: {
          response: {
            data: {
              message: "This password is incorrect. Please re-enter your password."
            }
          }
        }

      })
    } catch (error) {
      console.log(error)
    }
  })
  await waitForDomChange()
  expect(MockAxios).toHaveBeenCalledTimes(1)
  await expect(getByTestId('error-msg')).toBeInTheDocument()
})

(code is tested) Using axios hooks make request then send error to form

 const [{ data, loading, error }, exec] = useAxios(
    {
      method: 'POST',
      url: 'oauth/token/',
      headers: { 'Content-Type': 'application/x-www-form-urlencoded' }
    },
    { manual: true }
  )  

return (
    <>
      {(loading || userDataLoading) && <Loader />}
      <Form
        onSubmit={onSubmit}
        error={error}
      />
    </>
  )

mockError object fails instanceof test

I have some code in an axios interceptor which returns an instance of a specific error in some error conditions. I have some code to test which tests for this error using instanceof.

I want to use jest-mock-axios to mock out this error condition and return this error object, but the implementation for mockError uses object.assign({}, error) which results in the instanceof test failing.

I was wondering if you could explain what the object.assign call achieves over just passing the supplied object through? Sorry, I'm fairly new to JavaScript - I'm sure I'll learn something by asking the question one way or another!

Setting defaults within production code causes TypeError during tests

Whenever defaults are set for axios in the code e.g. headers or baseUrl, when this code is tested using jest-mock-axios the following error is thrown:

TypeError: Cannot read property 'headers' of undefined at LoggedInContainer.setAuthHeader (src/App/Containers/LoggedInContainer.jsx:22:34) at new LoggedInContainer (src/App/Containers/LoggedInContainer.jsx:11:18) at ReactShallowRenderer.render (node_modules/react-test-renderer/cjs/react-test-renderer-shallow.development.js:131:26) at Object.test (src/App/__tests__/Containers/LoggedInContainer.jsx:31:33) at new Promise (<anonymous>) at Promise.resolve.then.el (node_modules/p-map/index.js:46:16) at <anonymous> at process._tickCallback (internal/process/next_tick.js:188:7)

Not all valid instance methods are supported

Testing the following code:

import axios from 'axios';
import { API_ROOT } from './api.config';

const baseAPI = axios.create({
    baseURL: API_ROOT
});

export default (method, url, payload, config = {}) => {
    switch (method.toLowerCase()) {
        case 'get':
        case 'head':
        case 'delete':
        case 'options':
            return baseAPI[method](url, config);
        case 'post':
        case 'put':
        case 'patch':
            return baseAPI[method](url, payload, config);
        default:
            throw new Error('CMS: Http method not specified!');
    }
};

Tests work fine for get, delete, post and put, but fail for head, options and patch because jest-mock-axios doesn't seem to support them. I realize they're rarely used nowadays, but is it possible to add support for the sake of completeness?

issue: two axios calls in tested function but only one (first) response ever can be referenced

Hi guys, thanks for cool lib!

I'm trying to test async service that is returning response object and includes few intertwined API calls (axios with interceptors). Right now I'm using jest-mock-axios lib:

(I removed irrelevant parts of code, originally written in TS)

// services/persons.js
import personsAgent from '../agents/persons';
import places from './places';
[...]
const get = async ({ search = '', limit, offset }) => { 
  const places = await places.get({ search: '', limit: 1000, offset: 0 });  // api call to endpoint url '/places/'
  const params = {
    search: !!search.length ? search : null,
    limit,
    offset,
  };
  [...]
  return personsAgent.getAll({ ...params }).then(resp => {
    const results = sort(resp.data.results, .....).map((person, i) => {
      const place = places?.data?.results.filter(.....);

      return {
        id: person.id,
        name: person.first_name,
        surname: person.last_name,
        place,
      };
    });

    return {
      data: { ...resp.data, results },
      status: resp.status,
    };
  });
};
[....]
export default {
  get,
};
// agents/persons.js
import requests from '../utils/axios'; 
export default {
  getAll: (params: object) => requests.get('/persons/', { params }),
}
// services/persons.test.js
import mockAxios from 'jest-mock-axios';
import persons from './persons';

afterEach(() => {
  mockAxios.reset();
});

it('returns Persons data from API', async () => {
    let catchFn = jest.fn(),
      thenFn = jest.fn();

    persons
      .get({ search: '', limit: 10, offset: 0 })
      .then(thenFn)
      .catch(catchFn);

    expect(mockAxios.get).toHaveBeenCalledWith('/persons/', {
      params: { search: null, limit: 10, offset: 0 },
    }); // FAIL - received: '/places/', { search: null, limit: 1000, offset: 0 }

    let responseObj = {
      data: {
        results: ['test'],
      },
    };

    mockAxios.mockResponse(responseObj);

    expect(thenFn).toHaveBeenCalledWith({
      data: {
        results: ['test'],
      },
      status: 200,
    });

    expect(catchFn).not.toHaveBeenCalled();
  });

I'm using axios mock and for my others, simpler tests of services but without additional, internal calls and everything is working fine, but this one is problematic.
How to ignore or mock const places = await places.get() to focus on personsAgent.getAll()?
Issue right now is that I'm testing request for const places = await places.get() and there is no secondary request for personsAgent.getAll().
axios.getReqByUrl('/persons/') // = null

Any ideas? Thx in advance!

Is there a better way to separate multiple requests with the same url and methodโ€“eg. params?

I have two calls to the same endpoints that happen in parallel without guaranteed order, let's just say for simplicity:

GET /api/request { params: { supported: true } }
GET /api/request { params: { supported: false } }

It looked like I could've attempted to resolve this like so, but it didn't feel scalable (I didn't try):

getReqByRegex({ url: /\/api\/request/, config: /params.*supported=true/ });
getReqByRegex({ url: /\/api\/request/, config: /params.*supported=false/ });

This is how I resolved it, basically writing my own getReqMatching(criteria) and iterating over the queue directly instead. This is fine actually, I just expect a major version bump in this repo may require a rewrite of my repo's code is all.

Would this be something you'd consider a PR on? I just wanted to pop the issue even if I do open a PR later.

My primary concern was AxiosRequestConfig['params'] is typed as any in Axios, but I am explicitly treating it as an object and comparing that all of the params in criteria are in the QueueItem.config.params object as well.

/** Find the request in the queue based on: criteria: `url`, `method`, and `params`. */
const request = queue.find((item: AxiosMockQueueItem) => {
  /** If we provided a method and it didn't match, this is not the request. */
  if (method !== undefined && method?.toLowerCase() !== item.method?.toLowerCase()) {
    return false;
  }

  /** If we provided a url and it didn't match, this is not the request. */
  if (url !== undefined && url !== item.url) return false;

  if (
    params !== undefined &&
    item.config.params !== undefined &&
    isObject(item.config.params) // EXAMPLE NOTE: This is an internal function, think lodash/isObject
  ) {
    /** If all of the params from our config are in the request, we've found the correct request. */
    const hasAllCriteriaParams = Object.entries(params).every(
      ([key, value]) => item.config.params[key] === value
    );

    if (!hasAllCriteriaParams) return false;
  }

  return true;
});

if (!request) throw new Error('โ€ฆ');

mockResponse({ data }, request);

.finally is not a function

Hi, i'm getting this error in my test:

      Error: Uncaught [TypeError: _api.default.search(...).then(...).finally is not a function]

So I tried to do a simple:

import axios from 'jest-mock-axios';

console.log(axios.post().finally);

and got undefined

version: 3.0.0

TypeError when trying to use mockResponse

Receiving this error when trying to use axiosMock.mockResponse.

TypeError: Cannot read property 'resolve' of undefined
    at Function.i.mockResponse (/Users/myusername/projects/theproject/frontend/node_modules/jest-mock-axios/dist/webpack:/lib/mock-axios.ts:104:26)
    at Object.<anonymous> (/Users/myusername/projects/theproject/frontend/api-sdk/__tests__/billing.test.js:17:15)
    at resolve (/Users/myusername/projects/theproject/frontend/node_modules/jest-jasmine2/build/queue_runner.js:52:12)
    at Promise (<anonymous>)
    at mapper (/Users/myusername/projects/theproject/frontend/node_modules/jest-jasmine2/build/queue_runner.js:39:19)
    at promise.then (/Users/myusername/projects/theproject/frontend/node_modules/jest-jasmine2/build/queue_runner.js:73:82)
    at <anonymous>
    at process._tickCallback (internal/process/next_tick.js:188:7)

Here's my test (billing.test.js):

import {
    getAllAccounts
} from '../billing'

import mockAxios from 'jest-mock-axios'

const headers = new Headers({
    'content-type': 'application/json'
})

beforeEach(() => {
    jest.resetAllMocks()
})

test('getAllAccounts', done => {
    let response = {
        data: [
            {
                id: 1
            }
        ]
    }
    
    mockAxios.mockResponse(response)
    const account = getAllAccounts().then(accounts => {
        expect(mockAxios.calls).toMatchSnapshot()
        expect(account).toEqual(undefined)
        done()
    })
})

I have created the mocks folder. My structure looks like this:

my_project
---- ...unrelated folders...
---- frontend
-------- __mocks__
------------ axios.js
-------- node_modules
-------- package.json
-------- api-sdk
------------ billing.js
------------ __tests__
---------------- __snapshots__
---------------- billing.test.js

axios.js:

import mockAxios from 'jest-mock-axios';
export default mockAxios;

package.json:

"devDependencies": {
    ...
    "jest": "^22.4.4",
    "jest-mock-axios": "^2.1.11",
    ...
  },

What am I doing wrong here?

mockAxios.create() may return a new instance of mockAxios

Assuming the following use case:

// api.js
import axios from 'axios';

export function config() {
  v1.defaults.baseURL = `${API_BASEURL}/v1`;
  v2.defaults.baseURL = `${API_BASEURL}/v2`;
  // ...
}

export const v1 = axios.create();
export const v2 = axios.create();
export default v1;

Basic test scenario:

// api.test.js
import mockAxios from 'axios';
import * as Api form './api'

describe('Api', () => {
  test('proper configuration', () => {
    Api.config();

    // the following expectation fails because `mockAxios.create()` returns the singleton
    // whose `defaults.baseURL` was overwritten with `${API_BASEURL}/v2` already
    expect(Api.v1.defaults.baseURL).toEqual(`${API_BASEURL}/v1`);
    expect(Api.v2.defaults.baseURL).toEqual(`${API_BASEURL}/v2`);
  })
})

Because mockAxios works with a shared state, a workaround would be to override the create method and simply return a shalow copy of mockAxios (as in the following example) Since axios.create() actually appears to be a factory, the mock could also return a new instance. I think this would be ideal. What do you guys think?

//__mocks__/axios.js
import mockAxios from 'jest-mock-axios';
import { cloneDeep } from 'lodash';

mockAxios.create = jest.fn(() => cloneDeep(mockAxios));

export default mockAxios;

New viersion

Hello, could you publish a new version containing the patch for axios.create pleeease? ๐Ÿ˜„

Axios catch error Request failed with status code 404

i am setting up unit test with jest in my vuejs project.

testing with login component and i have tested successful all the props, input, client validation, but when i test with axios request POST then always return catch error

Error: Request failed with status code 404

console.log node_modules/raven-js/src/console.js:35 { Error: Request failed with status code 404 at createErrorResponse (/Users/artixun/Priyesh/Vue/work/e3-unit-test/node_modules/axios-mock-adapter/src/utils.js:117:15) at Object.settle (/Users/artixun/Priyesh/Vue/work/e3-unit-test/node_modules/axios-mock-adapter/src/utils.js:97:16) at handleRequest (/Users/artixun/Priyesh/Vue/work/e3-unit-test/node_modules/axios-mock-adapter/src/handle_request.js:78:11) at /Users/artixun/Priyesh/Vue/work/e3-unit-test/node_modules/axios-mock-adapter/src/index.js:18:9 at new Promise (<anonymous>) at MockAdapter.<anonymous> (/Users/artixun/Priyesh/Vue/work/e3-unit-test/node_modules/axios-mock-adapter/src/index.js:17:14) at dispatchRequest (/Users/artixun/Priyesh/Vue/work/e3-unit-test/node_modules/axios/lib/core/dispatchRequest.js:59:10) at process._tickCallback (internal/process/next_tick.js:68:7) config: { transformRequest: { '0': [Function: transformRequest] }, transformResponse: { '0': [Function: transformResponse] }, timeout: 0, xsrfCookieName: 'XSRF-TOKEN', xsrfHeaderName: 'X-XSRF-TOKEN', maxContentLength: -1, validateStatus: [Function: validateStatus], headers: { Accept: 'application/json, text/plain, */*', Accepts: 'application/json', 'Access-Control-Allow-Origin': '*' },   

i am setting up unit test with jest in my vuejs project.

testing with login component and i have tested successful all the props, input, client validation, but when i test with axios request POST then always return catch error

Error: Request failed with status code 404

login.spec.js

import Vue from 'vue'
import { shallowMount, createLocalVue } from '@vue/test-utils';
import Login from '../../src/components/global/login/Login.vue';
import Raven from "raven-js";
import jQuery from 'jquery'
import Vuex from 'vuex'
import router from '../../src/router'
var axios = require('axios');
var MockAdapter = require('axios-mock-adapter');

describe('Login.vue', () => {
let wrapper;
let componentInstance;
let mock;
beforeEach(() => {
    global.requestAnimationFrame = setImmediate,
    mock = new MockAdapter(axios)
    wrapper = shallowMount(Login, {
 router,
 $: jQuery,
 attachToDocument: true,
 mocks: {
   $t: () => { },
   Raven: Raven,
 },
data() {
      return {
         email: '',
        password: '',
      }
    }
  })
  componentInstance = wrapper.vm;
 })

  afterEach(() => {
   mock.reset()
})

my test code

 it('calls `axios()` with `endpoint`, `method` and `body`',async () => {
   const formData = {
     email: '[email protected]',
     password: '111111'
   };

  let fackData = {"fack response"}
  mock.onPost(`${process.env.VUE_APP_BASE_URL}/login/`, 
  formData).reply(200, fackData);


   wrapper.vm.email = '[email protected]';
   wrapper.vm.password = 'aaaaaaa';
   wrapper.vm.doSigninNormal()
  });

Login.vue

 doSigninNormal() {
  const formData = {
  email: this.email,
  password: this.password
   };
   this.$v.$touch()
   if(this.$v.$invalid ){
        this.loading = false;
        this.emailLostFocus = true;
        this.passwordLostFocus = true;
        $('html, body').animate({scrollTop:110}, 'slow')
    }
   else{
     axios
        .post("/login", formData, {
           headers: { "X-localization": localStorage.getItem("lan") }
        })
        .then(res => {
         console.log('then',res);
         if (!res.data.result) {
               if (res.data.errors) {
                   for (var i = 0; i < res.data.errors.length; i++) {
                       this.$toaster.error(res.data.errors[i].message);
               if (
                     res.data.errors[0].message == "Your email is not yet verified"
                 ) {
                  this.showVerificationLinkButton = true;
                  }
                if (res.data.errors[i].field === "email") {
                    this.$toaster.error(res.data.errors[i].message);
                 }
           if (res.data.errors[i].field === "password") {
            this.$toaster.error(res.data.errors[i].message);
            }
           }
        }

        this.loading = false;
         this.$v.$reset();
         } else {
        this.loading = false;
       Raven.setUserContext({
          email: res.data.user.email,
           id: res.data.user.id
         });
       this.$store.dispatch("login", res);
      this.$v.$reset();
      }
    })
     .catch((err) => {
         console.log('catch',err);
     });

i am trying to lot. how to moke axios by calling method? positive answer appreciate

i want to call function and then call api(inside the function) and get response. wrapper.vm.doSigninNormal()

i have also post on stackOverflow to describe it.

getReqByUrl needs to fail if there is no matching request

Let's say I have this code in my test:

mockAxios.mockResponse({...}, mockAxios.getReqByUrl('invalid.url'));

This will be equivalent to

mockAxios.mockResponse({...}, undefined);

so it will silently respond to the latest request, which may be the correct one - but the fact that it's not the URL I specified will be lost.

I think getReqByUrl should return something that's not undefined or throw an error when there's no matching request. For the sake of backwards compatibility, a mustGetReqByUrl or optional strict argument to getReqByUrl could be added.

Request to add changelog

I've recently noticed that this package have been updated to 4.0.0. But It's hard to see all the changes since 3.2.0, I am currently on. I'd like to suggest adding a changelog, which would make it easier to update this package. This should also let dependabot handle this library better

mockAxios() isn't compatible with the axios("/get/reqest") call signature

When calling axios("/my/api/call"), mockAxios.mockResponseFor({ url: "/my/api/call" }) fails to find the request because the URL string is assigned to the config property.

Everything works as expected when using axios.get("/my/api/call") instead as a workaround.

const _newReq: (config?: any) => UnresolvedSynchronousPromise<any> = (config: any = {}) => {
const method: string = config.method;
const url: string = config.url;
const data: any = config.data;

axios.mockErrorFor

Hello,

First of all, great job for this lib, I like it a lot. :)

Just a request if it's possible to do a function axios.mockErrorFor which will behave same as axios.mockResponseFor but sending an error ?

Or is there a workaround to do it ?

Thanks !

Testing code using an Axios instance

Hi everyone,

I've been looking online for some guidance on how to test code that is calling an instance of Axios rather than just something like axios.post(...), and am really at a loss. I've been using this library, which is fantastic, but am really stuck here and feel like I might be missing something. An example of the code I'm trying to test could look like this:

const axiosInstance = axios.create({
  baseUrl: "https://www.abc.dev/api"
});

axiosInstance.get("/list");

My impulse to test code like this would be to mock the return value of axios.create, is that necessary? Is there something in this library that I'm missing that would be useful there? Thanks very much for your time, and my apologies if this isn't the best place to ask for advice on this. I should also note that I'm working with TypeScript if that's helpful.

Question: Using jest-mock-axios with async / await

Hei there I have the following question:

My test looks like this:

import AddMeetingModal from '@/components/meeting/AddMeetingModal.vue';
import mockAxios from 'jest-mock-axios';

afterEach(() => { mockAxios.reset(); });

describe('Add Meeting Modal', () => {
  test('current date is passed to the backend when submitting', async (done) => {
    freezeTime(new Date('2018-01-01T07:30'));

    const modal = await localShallow(AddMeetingModal);
    modal.setData({ show: true });

    modal.vm.submit().then(() => {
      expect(modal.vm.show).toBe(false);
      done(); // How can I get rid of this
    });

    mockAxios.mockResponse({ data: { id: 1, title: 'Regierungssitzung vom 11.10.2018' } });
    expect(mockAxios.post.mock.calls[0][1].begin).toEqual('2018-01-01T07:30:00.000Z');
  });
});

As you can see I rely on the done in the callback of the submit method of the component. The show property is set to true when the submit is finished.

So how do I do the same with await, because the then is a bit ugly in my opinion and makes the code more complicated?

When I await the submit, it never resolves because of the missing mockResponse. When I do the mockResponse before the submit, I get No request to respond to!.

Do you have any idea?

axiosClientInstance.interceptors.request.use not supported?

The code I'm trying to test looks like this:

const axiosClientInstance = axios.create(someConfigObject);
axiosClientInstance.interceptors.request.use((config) => {
    config.headers.common['Access-Token'] = accessToken;
    return config;
});

Jest gives the following error:

TypeError: Cannot read property 'request' of undefined

Had to resort to some trickery to stub the call to the interceptors, but I'm not sure this worked:

// __mocks__/axios.js

import mockAxios from 'jest-mock-axios';

export default {
    ...mockAxios,
    ...{
        create: jest.fn(() => ({
            ...mockAxios,
            interceptors: {
                request: {
                    use: jest.fn()
                }
            }
        })),
    }
};

After doing this, axiosClientInstance.put() does not return a promise anymore. Is there any way currently to stub the interceptors properly?

mockAxios.post not working

I have following code:

describe('trackConversion', () => {
    it('should be called with following parameters', async () => {
      const experiment = {
        id: '--experiment-id--'
      }
      const variant = new PrizmoVariant(experiment, '--variant-id--')
      variant.baseUrl = process.env.BASE_URL
      variant.collectFeatures = jest.fn(() => ({}))
      const result = await variant.trackConversion({
        probability: 1
      })
      expect(result).toBeEqual({})
      expect(mockAxios.post).toHaveBeenCalledWith(
        `${process.env.BASE_URL}/trackConversion`,
        {
          eid: experiment.id,
          vid: variant.id,
          probability: 1,
          features: {}
        }
      )
    })
  })

And variant.trackConversion code:

  async trackConversion ({ probability }) {
    await axios.post(
      `${this.baseUrl}/trackConversion`,
      {
        eid: this.experiment.id,
        vid: this.id,
        probability,
        features: await this.collectFeatures(),
        ts: new Date()
      },
      { withCredentials: true }
    )
  }

And this test fails with reason Timeout - Async callback was not invoked within the 5000ms timeout specified by jest.setTimeout.

This means, execution never reach expect(result).toBeEqual({}) line.

This means jest-mock-axios not working.

How to use with ES5 require() syntax

I'm having a heckuva time trying to use this with ES5 syntax. Doing this results in an object that has a .default property but calling mockAxios.reset() wouldn't work.

const mockAxios = require('jest-mock-axios')
afterEach(() => {
  // cleaning up the mess left behind the previous test
  mockAxios.reset()
})

This appears like it might work:

const mockAxios = require('jest-mock-axios').default
afterEach(() => {
  // cleaning up the mess left behind the previous test
  mockAxios.reset()
})

However, attempting to make calls against the mocked Axios results in an async timeout because responses never return from the mocked axios calls.

      const response = await axios(options)

Similarly, attempting to do something like this:

const responseData = [
  {
    userId: 1,
    id: 1,
    title: 'My First Album'
  },
  {
    userId: 1,
    id: 2,
    title: 'Album: The Sequel'
  }
]
mockAxios.mockResponseFor({ url: '/', method: 'get' }, responseData)

results in a "No request to respond to!" error.

What am I doing wrong here?

Mocking nested axios requests

axios.request({
  url: "a",
  method: "post",
  data: "abc"
}).then((response) => {
  if(response.status === 200) {
    axios.request({
      url: "b",
      method: "get"
    }).then((response) => {
      if(response.status === 200)
        // Do something with response.data
    });
  }
});

const firstRequest = mockAxios.getReqByUrl("a"); // Returns correct request
const secondRequest = mockAxios.getReqByUrl("b"); // Returns correct request
expect(mockAxios.request).toBeCalledTimes(2); // Succeeds
mockAxios.mockResponse({ data: "" }, firstRequest);
mockAxios.mockResponse({ data: "" }, secondRequest);

With this code being used in a test, I can't get the nested axios.request to be completed before the test is complete. I've tried using a fake jest timer to allow the test extra time in case I was just ending the test before the promises were resolved, but it didn't help anything.

Could anyone show an example of mocking nested requests with jest-mock-axios?

To clarify: The test is succeeding, however the nested axios request in the code being tested is not being covered by jest. The second nested request seems to call axios.request properly, but .then((response) => ...); is never run.

Thanks!

Doesn't work in native ESM

To continue where #68 (comment) left off:

The basic example from the docs does not work in native ESM. A simple:

import mockAxios from 'jest-mock-axios';
console.log(mockAxios);

shows that everything is nested under a property called default:

    {
      default: [Function: mockConstructor] {
        ...
      }
    }
Full object copy
{
    default: [Function: mockConstructor] {
      _isMockFunction: true,
      getMockImplementation: [Function (anonymous)],
      mock: [Getter/Setter],
      mockClear: [Function (anonymous)],
      mockReset: [Function (anonymous)],
      mockRestore: [Function (anonymous)],
      mockReturnValueOnce: [Function (anonymous)],
      mockResolvedValueOnce: [Function (anonymous)],
      mockRejectedValueOnce: [Function (anonymous)],
      mockReturnValue: [Function (anonymous)],
      mockResolvedValue: [Function (anonymous)],
      mockRejectedValue: [Function (anonymous)],
      mockImplementationOnce: [Function (anonymous)],
      mockImplementation: [Function (anonymous)],
      mockReturnThis: [Function (anonymous)],
      mockName: [Function (anonymous)],
      getMockName: [Function (anonymous)],
      get: [Function: mockConstructor] {
        _isMockFunction: true,
        getMockImplementation: [Function (anonymous)],
        mock: [Getter/Setter],
        mockClear: [Function (anonymous)],
        mockReset: [Function (anonymous)],
        mockRestore: [Function (anonymous)],
        mockReturnValueOnce: [Function (anonymous)],
        mockResolvedValueOnce: [Function (anonymous)],
        mockRejectedValueOnce: [Function (anonymous)],
        mockReturnValue: [Function (anonymous)],
        mockResolvedValue: [Function (anonymous)],
        mockRejectedValue: [Function (anonymous)],
        mockImplementationOnce: [Function (anonymous)],
        mockImplementation: [Function (anonymous)],
        mockReturnThis: [Function (anonymous)],
        mockName: [Function (anonymous)],
        getMockName: [Function (anonymous)]
      },
      post: [Function: mockConstructor] {
        _isMockFunction: true,
        getMockImplementation: [Function (anonymous)],
        mock: [Getter/Setter],
        mockClear: [Function (anonymous)],
        mockReset: [Function (anonymous)],
        mockRestore: [Function (anonymous)],
        mockReturnValueOnce: [Function (anonymous)],
        mockResolvedValueOnce: [Function (anonymous)],
        mockRejectedValueOnce: [Function (anonymous)],
        mockReturnValue: [Function (anonymous)],
        mockResolvedValue: [Function (anonymous)],
        mockRejectedValue: [Function (anonymous)],
        mockImplementationOnce: [Function (anonymous)],
        mockImplementation: [Function (anonymous)],
        mockReturnThis: [Function (anonymous)],
        mockName: [Function (anonymous)],
        getMockName: [Function (anonymous)]
      },
      put: [Function: mockConstructor] {
        _isMockFunction: true,
        getMockImplementation: [Function (anonymous)],
        mock: [Getter/Setter],
        mockClear: [Function (anonymous)],
        mockReset: [Function (anonymous)],
        mockRestore: [Function (anonymous)],
        mockReturnValueOnce: [Function (anonymous)],
        mockResolvedValueOnce: [Function (anonymous)],
        mockRejectedValueOnce: [Function (anonymous)],
        mockReturnValue: [Function (anonymous)],
        mockResolvedValue: [Function (anonymous)],
        mockRejectedValue: [Function (anonymous)],
        mockImplementationOnce: [Function (anonymous)],
        mockImplementation: [Function (anonymous)],
        mockReturnThis: [Function (anonymous)],
        mockName: [Function (anonymous)],
        getMockName: [Function (anonymous)]
      },
      patch: [Function: mockConstructor] {
        _isMockFunction: true,
        getMockImplementation: [Function (anonymous)],
        mock: [Getter/Setter],
        mockClear: [Function (anonymous)],
        mockReset: [Function (anonymous)],
        mockRestore: [Function (anonymous)],
        mockReturnValueOnce: [Function (anonymous)],
        mockResolvedValueOnce: [Function (anonymous)],
        mockRejectedValueOnce: [Function (anonymous)],
        mockReturnValue: [Function (anonymous)],
        mockResolvedValue: [Function (anonymous)],
        mockRejectedValue: [Function (anonymous)],
        mockImplementationOnce: [Function (anonymous)],
        mockImplementation: [Function (anonymous)],
        mockReturnThis: [Function (anonymous)],
        mockName: [Function (anonymous)],
        getMockName: [Function (anonymous)]
      },
      delete: [Function: mockConstructor] {
        _isMockFunction: true,
        getMockImplementation: [Function (anonymous)],
        mock: [Getter/Setter],
        mockClear: [Function (anonymous)],
        mockReset: [Function (anonymous)],
        mockRestore: [Function (anonymous)],
        mockReturnValueOnce: [Function (anonymous)],
        mockResolvedValueOnce: [Function (anonymous)],
        mockRejectedValueOnce: [Function (anonymous)],
        mockReturnValue: [Function (anonymous)],
        mockResolvedValue: [Function (anonymous)],
        mockRejectedValue: [Function (anonymous)],
        mockImplementationOnce: [Function (anonymous)],
        mockImplementation: [Function (anonymous)],
        mockReturnThis: [Function (anonymous)],
        mockName: [Function (anonymous)],
        getMockName: [Function (anonymous)]
      },
      request: [Function: mockConstructor] {
        _isMockFunction: true,
        getMockImplementation: [Function (anonymous)],
        mock: [Getter/Setter],
        mockClear: [Function (anonymous)],
        mockReset: [Function (anonymous)],
        mockRestore: [Function (anonymous)],
        mockReturnValueOnce: [Function (anonymous)],
        mockResolvedValueOnce: [Function (anonymous)],
        mockRejectedValueOnce: [Function (anonymous)],
        mockReturnValue: [Function (anonymous)],
        mockResolvedValue: [Function (anonymous)],
        mockRejectedValue: [Function (anonymous)],
        mockImplementationOnce: [Function (anonymous)],
        mockImplementation: [Function (anonymous)],
        mockReturnThis: [Function (anonymous)],
        mockName: [Function (anonymous)],
        getMockName: [Function (anonymous)]
      },
      all: [Function: mockConstructor] {
        _isMockFunction: true,
        getMockImplementation: [Function (anonymous)],
        mock: [Getter/Setter],
        mockClear: [Function (anonymous)],
        mockReset: [Function (anonymous)],
        mockRestore: [Function (anonymous)],
        mockReturnValueOnce: [Function (anonymous)],
        mockResolvedValueOnce: [Function (anonymous)],
        mockRejectedValueOnce: [Function (anonymous)],
        mockReturnValue: [Function (anonymous)],
        mockResolvedValue: [Function (anonymous)],
        mockRejectedValue: [Function (anonymous)],
        mockImplementationOnce: [Function (anonymous)],
        mockImplementation: [Function (anonymous)],
        mockReturnThis: [Function (anonymous)],
        mockName: [Function (anonymous)],
        getMockName: [Function (anonymous)]
      },
      head: [Function: mockConstructor] {
        _isMockFunction: true,
        getMockImplementation: [Function (anonymous)],
        mock: [Getter/Setter],
        mockClear: [Function (anonymous)],
        mockReset: [Function (anonymous)],
        mockRestore: [Function (anonymous)],
        mockReturnValueOnce: [Function (anonymous)],
        mockResolvedValueOnce: [Function (anonymous)],
        mockRejectedValueOnce: [Function (anonymous)],
        mockReturnValue: [Function (anonymous)],
        mockResolvedValue: [Function (anonymous)],
        mockRejectedValue: [Function (anonymous)],
        mockImplementationOnce: [Function (anonymous)],
        mockImplementation: [Function (anonymous)],
        mockReturnThis: [Function (anonymous)],
        mockName: [Function (anonymous)],
        getMockName: [Function (anonymous)]
      },
      options: [Function: mockConstructor] {
        _isMockFunction: true,
        getMockImplementation: [Function (anonymous)],
        mock: [Getter/Setter],
        mockClear: [Function (anonymous)],
        mockReset: [Function (anonymous)],
        mockRestore: [Function (anonymous)],
        mockReturnValueOnce: [Function (anonymous)],
        mockResolvedValueOnce: [Function (anonymous)],
        mockRejectedValueOnce: [Function (anonymous)],
        mockReturnValue: [Function (anonymous)],
        mockResolvedValue: [Function (anonymous)],
        mockRejectedValue: [Function (anonymous)],
        mockImplementationOnce: [Function (anonymous)],
        mockImplementation: [Function (anonymous)],
        mockReturnThis: [Function (anonymous)],
        mockName: [Function (anonymous)],
        getMockName: [Function (anonymous)]
      },
      create: [Function: mockConstructor] {
        _isMockFunction: true,
        getMockImplementation: [Function (anonymous)],
        mock: [Getter/Setter],
        mockClear: [Function (anonymous)],
        mockReset: [Function (anonymous)],
        mockRestore: [Function (anonymous)],
        mockReturnValueOnce: [Function (anonymous)],
        mockResolvedValueOnce: [Function (anonymous)],
        mockRejectedValueOnce: [Function (anonymous)],
        mockReturnValue: [Function (anonymous)],
        mockResolvedValue: [Function (anonymous)],
        mockRejectedValue: [Function (anonymous)],
        mockImplementationOnce: [Function (anonymous)],
        mockImplementation: [Function (anonymous)],
        mockReturnThis: [Function (anonymous)],
        mockName: [Function (anonymous)],
        getMockName: [Function (anonymous)]
      },
      interceptors: { request: [Object], response: [Object] },
      defaults: { headers: [Object] },
      popPromise: [Function (anonymous)],
      popRequest: [Function (anonymous)],
      mockResponse: [Function (anonymous)],
      mockResponseFor: [Function (anonymous)],
      mockError: [Function (anonymous)],
      isAxiosError: [Function (anonymous)],
      lastReqGet: [Function (anonymous)],
      lastPromiseGet: [Function (anonymous)],
      getReqMatching: [Function (anonymous)],
      getReqByUrl: [Function (anonymous)],
      getReqByMatchUrl: [Function (anonymous)],
      getReqByRegex: [Function (anonymous)],
      queue: [Function (anonymous)],
      reset: [Function (anonymous)],
      Cancel: [Function: Cancel],
      CancelToken: [Function: CancelToken],
      isCancel: [Function (anonymous)]
    }
  }

which in turn means any operation on mockAxios fails, like:

import mockAxios from 'jest-mock-axios'

afterEach(() => {
  mockAxios.reset();
}

as .reset() doesn't exist in the ESM default export of jest-mock-axios.

The following wouldn't work:

import { default as mockAxios } from 'jest-mock-axios';

as that's an alias for

import mockAxios from 'jest-mock-axios';

The only workaround for now is to update the __mocks__ snippet to:

import mockAxiosWithDefault from 'jest-mock-axios';
const mockAxios = mockAxiosWithDefault.default;
export default mockAxios;

and use that same strategy to import mockAxios in every test:

import mockAxiosDefault from "jest-mock-axios";
const mockAxios = mockAxiosDefault.default;

Multiple server responses

This is probably a feature request:
If the module I'm testing makes multiple axios calls, could the dev have more control for mocking responses based on request data? I guess if the calls order is guaranteed, your API still works (I like the queue approach you did) but if they are done e.g. using Promise.all or some other less predictable ways, I wonder what you could offer. ๐Ÿ˜„

Breaking in change in minor version bump 2.3.0

Hi,

it seems that the new version you just published contains a breaking change from 2.1.11.
Using it from typescript the spyFn function does not contains mock anymore, breaking tests :-(

Is it intended ?

Thanks

axios.CancelToken.source() returns `undefined`

jest-mock-axios version: 4.2.1
jest version: 26.6.0

Upgrading an existing React project by several versions, including going from Jest 24.x to Jest 26.x, and a ton of our tests which were mocking Axios are now failing with this error.

Minimal repro:

import axios from 'axios';

jest.mock('axios'); 

it('should not throw when getting a cancel token', () => {
	//arrange
	var cancelToken = axios.CancelToken;

	//act
	const source = cancelToken.source();

	//assert
	expect(source).toBeDefined();
	const token = source.token;
	expect(token).toBeDefined();
});

I have seen similar issues which were closed, such as this one, but I believe the minimal repro above is following the suggested pattern and the test is still failing on the first assert.

cancelToken

cancelToken.source() is undefined when ai run test you have mock example it?

TypeError: Cannot read property 'resolve' of undefined

I need help to understand this error message. The stack trace is:

at e.value (node_modules/jest-mock-axios/dist/webpack:/lib/mock-axios.ts:66:20)
at Object.<anonymous> (tests/loader.test.js:17:27)

I've followed the README and created a __mock__/axios.js file in the root.

// ./__mock__/axios.js
import mockAxios from 'jest-mock-axios'
export default mockAxios

I then created a simple test case in tests/loader.test.js:

import mockAxios from 'jest-mock-axios'
import dummyTest from './tmp/dummy'

afterEach(() => {
  // cleaning up the mess left behind the previous test
  mockAxios.reset()
})

it('is just an implementation to check that we can mock axios', () => {
  const dummyF = jest.fn()
  const dummyCatch = jest.fn()

  dummyTest('hello')
    .then(dummyF)
    .catch(dummyCatch)

  mockAxios.mockResponse({ data: 'world'})

  expect(mockAxios.get).toHaveBeenCalledWith('/foobar/', 'hello')

  expect(dummyF).toHaveBeenCalledWith('world')

  expect(dummyCatch).not.toHaveBeenCalled()
})

In `tests/tmp/dummy.js' I have:

import axios from 'axios'

export default function dummyTest (msg) {
  const loader = axios.get('/foobar/', { data: msg })

  return loader.then(data => 'world')
}

The result is:

FAIL  tests/loader.test.js
  โ— is just an implementation to check that we can mock axios

    TypeError: Cannot read property 'resolve' of undefined

      at e.value (node_modules/jest-mock-axios/dist/webpack:/lib/mock-axios.ts:66:20)
      at Object.<anonymous> (tests/loader.test.js:17:27)

Always going to catch function if we write catch block.

If we have both then() and catch() then no matter what we mock as a response, control is going to catch() only.
If we dont write catch() then it is working fine, but I need to handle error response in order to display error message.

Can you please help me with that?

Calling reset does not reset the axios mock function

You can call axios with code like the following:

 method: 'post',
 url: '/user/12345',
 data: {
   firstName: 'Fred',
   lastName: 'Flintstone'
 }
});```

This code is correctly mocked, and you can test it fine.
However calling axios.reset() will not reset the mock state for these functions

Unable to mock requests when testing API end point

First of all, thank you for this awesome lib ๐Ÿ™ .

When I test my api end point, I'm doing a black box testing, this means that I don't have the access to the code it self and all the tests are creating http requests using supertest package.

This lib expecting to "break" down the code so it will first "register" the promise, and then you will able to call mockResponse otherwise it will throw No request to respond to!.

The problem is that it I can't "break" down the async call.

It would be great to expose an "on.get" method which just registers the response and when the call comes resolves them with the registered response.

WDYT?

unexpected token error

Hi,

Sorry for the newbie question, but I'm having trouble running the README example. I've created the three files as explained, i ran npm i jest jest-mock-axios axios, and then i'm hitting that wall:

 FAIL  test/UppercaseProxy.spec.js
  โ— Test suite failed to run

    Jest encountered an unexpected token

    This usually means that you are trying to import a file which Jest cannot parse, e.g. it's not plain JavaScript.

    By default, if Jest sees a Babel config, it will use that to transform your files, ignoring "node_modules".

    Here's what you can do:
     โ€ข If you are trying to use ECMAScript Modules, see https://jestjs.io/docs/en/ecmascript-modules for how to enable it.
     โ€ข To have some of your "node_modules" files transformed, you can specify a custom "transformIgnorePatterns" in your config.
     โ€ข If you need a custom transformation specify a "transform" option in your config.
     โ€ข If you simply want to mock your non-JS modules (e.g. binary assets) you can stub them out with the "moduleNameMapper" config option.

    You'll find more details and examples of these config options in the docs:
    https://jestjs.io/docs/en/configuration.html

    Details:

    /home/gquintard/fun/jest/test/UppercaseProxy.spec.js:2
    import mockAxios from 'jest-mock-axios';
    ^^^^^^

    SyntaxError: Cannot use import statement outside a module

      at Runtime.createScriptFromCode (node_modules/jest-runtime/build/index.js:1350:14)

Test Suites: 1 failed, 1 total
Tests:       0 total
Snapshots:   0 total
Time:        1.483 s
Ran all test suites.

I tried node --experimental-vm-modules node_modules/.bin/jest, without success.

I'm sure the answer is obvious, but have little JS experience and I could really help a hand here

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.