3

Is there a reason why Jest would see this as a not identical when both seem exactly the same?

So here is the code I am using to do the test, it's basically just a function that calls for an event emiter, in the event emiter if the date is invalid, I let it as is :

  const datepickerComponent: Datepicker = new Datepicker();

  const mockEvent = {
    target: {
      classList: {
        remove: jest.fn(),
        add: jest.fn(),
      },
      value: '01-01-197',
    },
  } as unknown as InputEvent;

  datepickerComponent.onInput(mockEvent);

  const emitMock: jest.Mock = jest.fn();
  datepickerComponent.dsdDatepickerInputChange = { emit: emitMock } as unknown as EventEmitter<dsdDatepickerInputChangeEvent>;

  // when
  datepickerComponent.onInput(mockEvent);

  const dateValue = new Date('197-01-01T00:00:00');

  // then
  expect(emitMock).toHaveBeenCalledWith({ value: '197-01-01', valueAsDate: dateValue });

enter image description here

Steven
  • 817
  • 1
  • 8
  • 25
  • Maybe there is some strange Unicode character hidden in it, like a zero width space? You could try running it through [a Unicode analyzer](https://devina.io/unicode-analyser) – cocomac Jun 02 '22 at 17:43
  • 1
    doesn't seem like thats the case...I tested copy pasted both from the terminal... – Steven Jun 02 '22 at 17:46
  • Can you share some of the code, what kind of expect are you using and how are the compared objects being generated? – Ovidijus Parsiunas Jun 02 '22 at 19:20

2 Answers2

5

The reason why you are observing this error is because whilst Date { NaN } values look the same, they actually refer to different object instances and cannot be traversed for equality any further, hence the actual error should be the following:

Expected: {"value": "197-01-01", "valueAsDate": Date { NaN }}
Received: serializes to the same string

(To reproduce this error - create two new dates using new Date('197-01-01T00:00:00') and pass them into .equals())

To get past this error, all you need to do is to simply refactor your .toHaveBeenCalledWith test into the following:

const calledWithArg = emitMock.mock.calls[0][0];
expect(JSON.stringify(calledWithArg)).toEqual(JSON.stringify({ value: '197-01-01', valueAsDate: dateValue }));

The reason why .toHaveBeenCalledWith does not work is because it does not allow us to reshape the argument object before a comparison (in our case we need to stringify it), hence we can alternatively extract the argument that the mock was called with via .mock.calls[0][0], stringify it and then compare it to the stringified version of the expected object.

Ovidijus Parsiunas
  • 2,512
  • 2
  • 8
  • 18
0

Reference of valueAsDate is different. But Jest doc affirm it uses .toEqual for comparison. That means it try to deeply compare two new Date. This is a bad idea, you don't control the Date class, and there are probably some moving parts inside.

To loose match a value, you can check this issue: https://stackoverflow.com/a/55569458/7696155

Ambroise Rabier
  • 3,636
  • 3
  • 27
  • 38