模拟 dayjs 扩展 [英] Mocking dayjs extend

查看:19
本文介绍了模拟 dayjs 扩展的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

In my code that needs testing I use

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

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

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

In my test I need to mock dayjs in order to always have the same date when comparing snapshots in jest so I did

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?

Unfortunately similar questions on here didn't help me. How could I mock both default dayjs but also extend?

推荐答案

可以dayjs 编写一个更全面的手动模拟,一个具有 extend 方法,但随后您将测试耦合到 3rd 方接口.不要嘲笑你不拥有的东西" - 你最终不得不在你的模拟中重新创建越来越多的 dayjs 界面,然后如果该接口更改您的测试将继续通过,但您的代码将被破坏.或者,如果您决定切换到不同的时间库,则必须重写所有测试以手动模拟新界面.

You could write a more thorough manual mock for dayjs, one that has the extend method, but then you're coupling your tests to a 3rd party interface. "Don't mock what you don't own" - you'll end up having to recreate more and more of the dayjs interface in your mock, and then if that interface changes your tests will continue to pass but your code will be broken. Or if you decide to swap to a different time library, you have to rewrite all of your tests to manually mock the new interface.

相反,将时间视为依赖项.在您自己的模块中拥有您自己的函数,该函数仅将当前时间作为 Date 对象提供:

Instead, treat time as a dependency. Have your own function, in your own module, that simply provides the current time as a Date object:

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

然后,当你需要创建一个 dayjs 对象时,从那个开始(dayjs() 等价于 dayjs(new Date()) 根据文档):

Then, when you need to create a dayjs object, do so from that (dayjs() is equivalent to dayjs(new Date()) per the docs):

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:

Now in your test you can swap out something you actually own, and not have to interfere with dayjs at all:

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

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

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

现在,如果 dayjs 的新版本发生了改变,破坏了您对它的使用,您的测试将失败并告诉您同样的信息.或者,如果您切换到不同的时间库(这里是一个使用 Moment 的示例),您不必重写所有测试,因此您可以确信自己已正确切换.

Now if a new version of dayjs changes in a way that breaks your use of it, your tests will fail and tell you as much. Or if you swap to a different time library (here's an example using Moment) you don't have to rewrite all of your tests, so you can be confident you've swapped over correctly.

此外,FWIW 我一般不评价快照测试——它只是变成了变更检测,不相关的变更失败并鼓励人们忽略测试结果并在任何失败时盲目地重新创建快照.根据您希望从组件中看到的行为进行测试.

Also FWIW I don't rate snapshot testing in general - it just becomes change detection, failing for irrelevant changes and encouraging people to ignore the test results and blindly recreate the snapshots if anything fails. Test based on the behaviour you want to see from your components.

这篇关于模拟 dayjs 扩展的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆