typescript 嘲笑日延长

wnrlj8wa  于 2022-12-05  发布在  TypeScript
关注(0)|答案(3)|浏览(144)

在需要测试的代码中,我使用

import dayjs from 'dayjs';
import utc from 'dayjs/plugin/utc';
dayjs.extend(utc);

dayjs().add(15, 'minute')

在我的测试中,我需要模拟dayjs,以便在比较jest中的快照时始终具有相同的日期,所以我这样做了

jest.mock('dayjs', () =>
  jest.fn((...args) =>
    jest.requireActual('dayjs')(
      args.filter((arg) => arg).length > 0 ? args : '2020-08-12'
    )
  )
);

它会失败

TypeError: _dayjs.default.extend is not a function

不幸的是,类似的问题在这里没有帮助我。我怎么能嘲笑默认的dayjsextend

hfyxw5xn

hfyxw5xn1#

您 * 可以 * 为dayjs编写一个更全面的手动mock,这个mock包含extend方法,但是这样您就将测试耦合到了第三方接口。“不要mock您不拥有的东西” -您最终将不得不在mock中重新创建越来越多的dayjs接口,然后如果接口发生变化,您的测试将继续通过,但是 * 您的代码将被破坏 *。或者,如果您决定交换到不同的时间库,则必须重写所有测试以手动模拟新接口。
相反,把时间当作一种依赖关系,在你自己的模块中有你自己的函数,它只是把当前时间作为一个Date对象:

export const howSoonIsNow = () => new Date();

然后,当您需要创建dayjs对象时,* 从该对象开始 *(dayjs()相当于the docsdayjs(new Date())):

import dayjs from 'dayjs';
import utc from 'dayjs/plugin/utc';

import { howSoonIsNow } from './path/to/noTimeLikeThePresent';

dayjs.extend(utc);

dayjs(howSoonIsNow()).add(15, 'minute');

现在,在测试中,您可以交换出实际拥有的东西,而完全不必干扰dayjs

import { howSoonIsNow } from './path/to/noTimeLikeThePresent';

jest.mock('./path/to/noTimeLikeThePresent');

howSoonIsNow.mockReturnValue(new Date(2020, 8, 12));

现在,如果dayjs的新版本改变了你对它的使用方式,你的测试将失败,并告诉你同样的信息。或者,如果你换到一个不同的时间库(here's,一个使用Moment的例子),你不必重写你所有的测试,所以你可以确信你已经正确地交换了。
此外,FWIW我不评价快照测试--它只是变成了变化检测,不相关的变化会失败,并鼓励人们忽略测试结果,如果任何东西失败了,盲目地重新创建快照。测试基于您希望从组件中看到的 * 行为 *。

gorkyyrv

gorkyyrv2#

您可以尝试以下操作:

jest.mock('dayjs/plugin/utc', () => ({
  default: jest.requireActual('dayjs/plugin/utc'),
}));

对我有用。

s1ag04yj

s1ag04yj3#

模拟dayjs像你希望的那样,不要忘记设置静态函数如下:

import dayjs from "dayjs";

jest.mock('dayjs', () =>
  jest.fn((...args) =>
    jest.requireActual('dayjs')(
      args.filter((arg) => arg).length > 0 ? args : '2020-08-12'
    )
  )
);

dayjs.extend = jest.fn();

相关问题