javascript - How can I disable a jest mock for a particular test? - Stack Overflow

I have created a working Mock for Axios: __mocks__axios.js Based on const axios = jest.createMoc

I have created a working Mock for Axios:

// __mocks__/axios.js
// Based on 

const axios = jest.createMockFromModule("axios");
const log = console.log.bind(console);

axios.create = () => {
  log(`Running axios.create`);
  return {
    get: () => {
      log(`Running get`);
      return {
        status: 500,
        statusText: "Internal Server Error",
        body: {
          onFire: "Mock API response from mock axios module",
        },
      };
    },
  };
};

module.exports = axios;

This works fine in my tests - the mock is loaded automatically and the 'throws an error' test works:

describe(`getLatestPrice`, () => {
  it(`throws an error when the response is bad`, async () => {
    expect(() => {
      log(`Should throw`);
      return getLatestPrice(assetCode);
    }).toThrow();
  });

  it(`gets a single price by stream code`, async () => {
    // Disabling the mock isn't working
    jest.unmock("axios");
    const price = await getLatestPrice(assetCode);
    log(`price`, price);
    expect(price).toEqual({
      ...
    });
  });
})

However the second test - which calls jest.unmock() - still uses the mocked library.

How can I disable mocking for a single test?

Update: reading I've also tried using requireActual() to override the mock:

const actualAxios = jest.requireActual("axios");
const mockAxios = require("axios");
mockAxios.create = actualAxios.create;

But calls to axios.create() still invole the mock.

I have created a working Mock for Axios:

// __mocks__/axios.js
// Based on https://jestjs.io/docs/manual-mocks

const axios = jest.createMockFromModule("axios");
const log = console.log.bind(console);

axios.create = () => {
  log(`Running axios.create`);
  return {
    get: () => {
      log(`Running get`);
      return {
        status: 500,
        statusText: "Internal Server Error",
        body: {
          onFire: "Mock API response from mock axios module",
        },
      };
    },
  };
};

module.exports = axios;

This works fine in my tests - the mock is loaded automatically and the 'throws an error' test works:

describe(`getLatestPrice`, () => {
  it(`throws an error when the response is bad`, async () => {
    expect(() => {
      log(`Should throw`);
      return getLatestPrice(assetCode);
    }).toThrow();
  });

  it(`gets a single price by stream code`, async () => {
    // Disabling the mock isn't working
    jest.unmock("axios");
    const price = await getLatestPrice(assetCode);
    log(`price`, price);
    expect(price).toEqual({
      ...
    });
  });
})

However the second test - which calls jest.unmock() - still uses the mocked library.

How can I disable mocking for a single test?

Update: reading https://github./facebook/jest/issues/2649 I've also tried using requireActual() to override the mock:

const actualAxios = jest.requireActual("axios");
const mockAxios = require("axios");
mockAxios.create = actualAxios.create;

But calls to axios.create() still invole the mock.

Share Improve this question edited Sep 1, 2021 at 14:35 mikemaccana asked Sep 1, 2021 at 11:23 mikemaccanamikemaccana 124k110 gold badges432 silver badges534 bronze badges 4
  • 1 Note to self: reading jestjs.io/docs/manual-mocks#mocking-user-modules "To opt out of this behavior you will need to explicitly call jest.unmock('moduleName') in tests that should use the actual module implementation." - unmock() doesn't seem to unmock a module like I thought but rather changes the mock that will be used. – mikemaccana Commented Sep 1, 2021 at 11:28
  • Looks like this may not be possible: github./facebook/jest/issues/2649 – mikemaccana Commented Sep 1, 2021 at 14:28
  • Actually, the link in @mikemaccana's ment has the answer, use jest.requireActual('moduleName') – picmate 涅 Commented Feb 13, 2022 at 3:00
  • 1 My context for wanting to turn off a mock was a manual mock of a node_module dependency. Using jest.unmock('module-name') worked for me. – SamBrick Commented Apr 1, 2022 at 10:05
Add a ment  | 

2 Answers 2

Reset to default 2

I had a similar problem with mocking useSelector, which I wanted to behave normally in other tests. The only thing that eventually worked was to mock mocked useSelector with the actual useSelector. So first make sure to have way to access the actual module:

import {useSelector as actualUseSelector} from "react-redux"
import {useSelector} from "react-redux";

then I've done my mocking

jest.mock('react-redux', () => ({
  ...jest.requireActual('react-redux'),
  useSelector: jest.fn()
}));

inside tests that needed modified redux state added

useSelector.mockImplementation(callback => {
  return callback({
    sliceA: {...initialStateSliceA},
    sliceB: {...initialStateSliceB},
    sliceC: {...initialStateSliceC, importantData: [{d: 1}, {d: 2}]}
  })
})

and then in tests where I needed original useSelector

useSelector.mockImplementation(()=>actualUseSelector)

and it worked!

UPDATE

Actually the above solution doesn't work as intended, it worked in one case, but for wrong reasons. It was still a mock function (and if you think about it, it makes sense). But eventually I found a working solution:

you have to recreate the whole redux anew:

const actualRedux = jest.requireActual('react-redux')

and only then mock useSelector or useDispatch with the actual ones:

useSelector.mockImplementation(actualRedux.useSelector)
useDispatch.mockImplementation(actualRedux.useDispatch)

The style of mocking you perform is global mocking. All tests that use the "axios" instances in essence are hard wired to return a 500 response. To achieve per test behavior you will need to mock "axios" locally in the test. Then you can fix your mock in each test to respond in a way you expect it to.

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

相关推荐

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

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

关注微信