【问题标题】:How do I change the mock implementation of a function in a mock module in Jest如何在 Jest 的模拟模块中更改函数的模拟实现
【发布时间】:2020-10-15 06:31:48
【问题描述】:

我有一个类似这样的 utils 文件

// utils.js
const getNextDate = (startDate) => moment(startDate, 'MMM Do YYYY').startOf('day').add(10, 'days').format('MMM Do YYYY');
const getDisplayName = (user) => {
  if (user.type === 'admin') {
    return 'Admin';
  } else if (user.type === 'guest') {
    return 'Guest'
  } else if(user.type === 'user') {
    return `${user.firstname} ${user.lastname}`
  } else {
    return 'No user'
  }
}

export {
  getNextDate,
  getDisplayName
}

我的 mocks 文件夹中还有一个我的 utils 文件的模拟,我在其中实现模拟返回值以进行测试。它看起来像这样

// mock/utils.js
export const getNextDate = () => 'Oct 20th 2020';
export const getDisplayName = (user) => user

在我的组件和测试中,我正在做这样的事情

//Component.js
import React from 'react';
import { getNextDate, getDisplayName } from './utils'

export const Component = () => {
  const user = {
    type: 'admin',
    firstname: 'john',
    lastname: 'doe',
  }
  return (
    <div>
      <div>{getDisplayName(user)}</div>
      <div>{getNextDate(moment())}</div>      
    </div>
  )
}

// Component.test.js
import { Component } from '../Component'
jest.mock('./utils', () => require('./mock/utils'));

describe('Component', () => {
  beforeEach(() => {
    wrapper = shallow(
      <Component />
    );
  });

  it('renders next date', () => {
      // At this point, I want to change the mock return value of getNextDate to Dec 25th 2020 without changing it in mock/utils.js as other tests are using that value
      expect(wrapper.find('.date').text()).toEqual('Dec 25th 2020');
  });
});

但是,在其中一个测试用例中,我正在尝试更改 getNextDate 的模拟实现。由于我不能直接致电getNextDate.mockImplementation(),我该如何完成这项工作?

【问题讨论】:

  • 我不能直接调用 b.mockImplementation() - 是因为你没有使用 jest.fn 进行模拟吗?那就用吧。
  • 函数 b 没有在测试文件中定义,所以我会得到一个 ReferenceError。虽然它是导入的 utils 文件的一部分,但它不是命名导入
  • 请提供可以重现问题的stackoverflow.com/help/mcve。不要截断相关的导入和导出。 虽然它是导入的 utils 文件的一部分,但它不是命名导入 - 但它在“看起来像这样的 utils 文件”中命名为导出。
  • 我已经更新了问题
  • ReferenceError 是因为 getNextDate 没有被导入。但即使是这样,也应该是 Jest spy 来更改模拟实现。

标签: javascript jestjs mocking


【解决方案1】:

jest.mock('./utils', () =&gt; require('./mock/utils')) 重新发明了现有的 Jest 功能,__mocks__ manual mocks

它应该是__mocks__/utils.js 与原始模块处于同一级别并使用Jest spies 以使实现可变:

export const getNextDate = jest.fn(() => ...);
export const getDisplayName = jest.fn(() => ...);

考虑到__mocks__ 提供默认模拟,它们不应该被mockImplementation 覆盖以进行特定测试,因为这会影响后续测试。相反,应该使用*Once 模拟特定调用。对于在 beforeEach 中指定且对多个测试通用的包装器:

import { getNextDate } from './utils';
jest.mock('./utils')

...

  beforeEach(() => {
    wrapper = shallow(<Component />); // uses default mock
  });

  it('renders next date', () => {
    getNextDate.mockReturnValueOnce(...);
    wrapper.setProps({}); // update with new mock
    expect(wrapper.find('.date').text()).toEqual('Dec 25th 2020');
  });

【讨论】:

    猜你喜欢
    • 2017-02-06
    • 1970-01-01
    • 2019-08-17
    • 2021-11-17
    • 2021-04-19
    • 2019-12-26
    • 1970-01-01
    • 2018-06-21
    • 2019-02-09
    相关资源
    最近更新 更多