Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Mocking dayjs with Jest

I'm new to test driven development, I'm trying to implement my simple testing but jest always finds my dayjs as not a function. Also i'm not using typescrcipt so my problem would be similar to this.

I can't seem to find how to setup my jest environment to recognise it as not default export.

Here's my simple test with failed mocking?:

import React from "react";
import { shallow } from "enzyme";
import MainDashboardApp from "../MainDashboard";

jest.mock("dayjs", () => {
  return () => jest.requireActual("dayjs")("2020-01-01T00:00:00.000Z");
});

describe("Inititate main dashboard", () => {
  it("renders without crashing", () => {
  ┊ shallow(<MainDashboardApp />);
  });
});

Error:

 FAIL  src/app/main/apps/dashboards/main/__tests__/dashboard.test.js
  ● Test suite failed to run

    TypeError: dayjs is not a function

       9 | import { tableData } from "../helpers";
      10 |
    > 11 | const defaultStart = dayjs().startOf("month").format("YYYY-MM-DD");
         |                      ^
      12 | const defaultEnd = dayjs().endOf("month").format("YYYY-MM-DD");
      13 |
      14 | function IncidentList({

      at Object.<anonymous> (src/app/main/apps/operations/incidents/IncidentList.js:11:22)
      at Object.<anonymous> (src/app/main/apps/index.js:1:1)
      at Object.<anonymous> (src/app/main/apps/dashboards/main/MainDashboard.js:22:1)
      at Object.<anonymous> (src/app/main/apps/dashboards/main/__tests__/dashboard.test.js:3:1)

Failed component (which actually renders in chrome):

 import React, { useEffect, useCallback, useState } from "react";
 import { connect } from "react-redux";
 import PropTypes from "prop-types";
 import * as incidents from "app/store/ducks/incident.duck";
 import MaterialTable, { MTableToolbar } from "material-table";
 import { useHistory } from "react-router-dom";
 import * as dayjs from "dayjs";
 import { DatePicker } from "@material-ui/pickers";
 import { tableData } from "../helpers";

 const defaultStart = dayjs().startOf("month").format("YYYY-MM-DD");
 const defaultEnd = dayjs().endOf("month").format("YYYY-MM-DD");

 function IncidentList({
   incidentsList,
   requestIncidents,
   selectedLoc,
   startDate,
   endDate,
 }) {
   const history = useHistory();
   const [selectedEndDate, handleEndDateChange] = useState(defaultEnd);
   const [selectedStartDate, handleStartDateChange] = useState(defaultStart);
   // Deps are ok because history constantly updates, and this handleclick does not need
   // to be updated as well
   const handleClick = useCallback((event, rowData) => {
     history.push({
       pathname: `/operation/incident-details/${rowData.id}`,
       state: { detail: "testing" },
     });
   }, []);

   useEffect(() => {
     if (startDate && endDate) {
       handleEndDateChange(endDate);
       handleStartDateChange(startDate);
     }
   }, [startDate, endDate]);

like image 757
DevBF Avatar asked Jul 02 '20 07:07

DevBF


1 Answers

MockDate works great for this, no intense mocking code required.

https://www.npmjs.com/package/mockdate

import MockDate from 'mockdate'
import dayjs from 'dayjs'

MockDate.set('2020-01-01')
console.log(dayjs.format())

// >>> 2019-12-31T18:00:00-06:00

Remember to clear the mock after your test with: MockDate.reset();

Also for your situation you probably want to use DayJS UTC to avoid unexpected date math results

https://day.js.org/docs/en/plugin/utc

like image 71
John Culviner Avatar answered Oct 08 '22 07:10

John Culviner