fullstackopen-2019 / fullstackopen-2019.github.io

Other
348 stars 356 forks source link

Part 4b: expect().toEqual() fails, comparing raw Date to string #645

Open niet-dev opened 4 years ago

niet-dev commented 4 years ago

Problem

In part 4b, the section Error handling and async/await contains a test that will fail:

test('a specific note can be viewed', async () => {
  const notesAtStart = await helper.notesInDb()

  const noteToView = notesAtStart[0]

  const resultNote = await api
    .get(`/api/notes/${noteToView.id}`)
    .expect(200)
    .expect('Content-Type', /application\/json/)

  expect(resultNote.body).toEqual(noteToView)
})

Specifically, Jest will take issue with the way the note's date is formatted:

    expect(received).toEqual(expected) // deep equality

    - Expected
    + Received

      Object {
        "content": "HTML is easy",
    -   "date": 2020-01-22T05:06:35.866Z,
    +   "date": "2020-01-22T05:06:35.866Z",
        "id": "5e27d85dc41be71f7cfd1ff6",
        "important": false,
      }

I'm not a Javascript wizard (hence why I'm taking this course), but it seems like Express really wants to parse the date field as a string, whereas MongoDB will return a raw Date as expected.

Proposed Solution

Modify the noteSchema's toJSON() transform to convert the date to a string when necessary:

noteSchema.set('toJSON', {
  transform: (document, returnedObject) => {
    returnedObject.id = returnedObject._id.toString()
    returnedObject.date = returnedObject.date.toString()
    delete returnedObject._id
    delete returnedObject.__v
  }
})

Or, maybe I'm dumb and missed something in the text. Either way wanted to bring this up.

Kaltsoon commented 4 years ago

Yes, this is definitely an issue. A weirdish fix for this could be serialize and parse the noteToView variable like so:

expect(resultNote.body).toEqual(JSON.parse(JSON.stringify(noteToView)))

This is basically what happens in the route handler anyway, but definitely requires as explanation.