如何禁用特定测试的jest mock?

6ojccjat  于 2023-06-20  发布在  Jest
关注(0)|答案(2)|浏览(188)

我为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;

这在我的测试中工作得很好-mock会自动加载,并且'throws an error'测试可以正常工作:

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({
      ...
    });
  });
})

然而,第二个测试(调用jest.unmock())仍然使用模拟库。

如何禁用单个测试的模拟?

更新:阅读https://github.com/facebook/jest/issues/2649我也尝试过使用requireActual()来覆盖mock:

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

但是对axios.create()的调用仍然涉及模拟。

ncecgwcz

ncecgwcz1#

我在模拟useSelector时也遇到了类似的问题,我希望在其他测试中表现正常。最终唯一起作用的是用实际的useSelector来模拟mock的useSelector。因此,首先确保有方法访问实际模块:

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

那我就嘲笑够了

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

添加了需要修改redux状态的内部测试

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

然后在需要原始useSelector的测试中

useSelector.mockImplementation(()=>actualUseSelector)

而且成功了

更新

实际上,上述解决方案并不像预期的那样工作,它在一种情况下工作,但由于错误的原因。它仍然是一个模拟函数(如果你仔细想想,它是有意义的)。但最终我找到了一个可行的解决方案:
你必须重新创造整个还原版:

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

然后才用实际的useSelector或useDispatch来模拟:

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

jckbn6z72#

您执行的模拟风格是全局模拟。所有使用“axios”示例的测试本质上都是硬连接的,以返回500响应。要实现每个测试的行为,您需要在测试中本地模拟“axios”。然后,您可以在每个测试中修复mock,使其以您期望的方式响应。

相关问题