Msw: Unable to call multiple times an endpoint during test

Created on 28 Dec 2020  路  3Comments  路  Source: mswjs/msw

Environment

| Name | Version |
| ---- | ------- |
| msw | 0.24.3 |
| node | 14.8.0 |
| OS | OSX 10.15.7 |

Request handlers


handlers

import { rest } from "msw"
import { cards } from "./cards"

localStorage.setItem("cards", JSON.stringify(cards))

const responseStructure = (data) => ({
  data,
})

const loadData = () => {
  return JSON.parse(localStorage.getItem("cards"))
}

const findById = (id) => {
  const data = loadData()
  return data.find((card) => card._id === id)
}

export const handlers = [
  rest.get("/cards", (_req, res, ctx) => {
    return res(ctx.json(responseStructure(loadData())))
  }),
  rest.delete("/cards/:cardId", (req, res, ctx) => {
    const card = findById(req.params.cardId)
    if (card) {
      const newData = loadData().filter(
        (card) => card._id !== req.params.cardId,
      )
      localStorage.setItem("cards", JSON.stringify(newData))
      return res(ctx.json(responseStructure(card)))
    } else {
      return res(ctx.status(404, "Not found"))
    }
  }),
  rest.put("/cards/:cardId", (req, res, ctx) => {
    const oldCard = findById(req.params.cardId)
    if (oldCard) {
      const body = JSON.parse(req.body)
      const newCard = { ...oldCard, ...body }
      const newData = loadData.map((card) => {
        if (card._id === newCard._id) {
          return newCard
        } else {
          return card
        }
      })
      localStorage.setItem("cards", JSON.stringify(newData))
      return res(ctx.json(responseStructure(newCard)))
    } else {
      return res(ctx.status(404, "Not found"))
    }
  }),
]

Server

import { setupServer } from "msw/node"
import { handlers } from "./handlers"

// Setup requests interception using the given handlers.
export const server = setupServer(...handlers)

Jest config

import "@testing-library/jest-dom/extend-expect"
import { server } from "./mocks/server"

beforeAll(() => {
  server.listen()
})

afterEach(() => {
  // Reset any runtime handlers tests may use.
  server.resetHandlers()
})

afterAll(() => {
  server.close()
})

jest environment

module.exports = {
  testEnvironment: "jest-environment-jsdom",
  setupFilesAfterEnv: ["@testing-library/jest-dom/extend-expect"],
}

Actual request

const buildRequest = async (
  path: string,
  options?: RequestInit | undefined,
) => {
  return fetch(`${path}`, Object.assign(BASE_HEADERS, options))
}

export const getCards = () => {
  return buildRequest("/cards")
}

export const deleteCard = (cardId: string) => {
  return buildRequest(`/cards/${cardId}`, { method: "DELETE" })
}

Current behavior

The following snippet of code fail after call the second getCards

    const AllCards = await getCards()
    const body = await AllCards.json()
    const cards = await body.data

    const cardToDelete = cards[0]
    const deletedCardResponse = await deleteCard(cardToDelete._id)
    const bodyDelete = await deletedCardResponse.json()
    const deletedCard = await bodyDelete.data

    expect(deletedCard).toStrictEqual(cardToDelete)

    const AllCardsAfterDelete = await getCards()
    const bodyAllCardsAfterDelete = await AllCardsAfterDelete.json()
    const cardsAfterDelete = await bodyAllCardsAfterDelete.data

    expect(
      none((card) => card._id === cardToDelete._id, cardsAfterDelete),
    ).toBeTruthy()
    expect(cardsAfterDelete).toHaveLength(71)

Expected behavior

I expected to be able to call any times the getCards functions because my handlers doesn't have the once modifier

Screenshots


imagen

bug node

Most helpful comment

I close it because I found the error, the mistake is on my side, while I was doing the CodeSanbox I detected it.

The error is on:

return fetch(`${path}`, Object.assign(BASE_HEADERS, options))

I am mutating the object BASE_HEADERS instead of create a new object. Plus the method getCards never overwrite the key method.

Sorry for the noise and keep going with this fantastic library 鉂わ笍

All 3 comments

Hi, I tried to reproduce this in the integration tests of this project and I wasn't able to.
Could you create a reproduction for us to take a look at please, because the shared code seems fine to me.

I close it because I found the error, the mistake is on my side, while I was doing the CodeSanbox I detected it.

The error is on:

return fetch(`${path}`, Object.assign(BASE_HEADERS, options))

I am mutating the object BASE_HEADERS instead of create a new object. Plus the method getCards never overwrite the key method.

Sorry for the noise and keep going with this fantastic library 鉂わ笍

Thanks for updating the issue @Afsoon 馃憤

Was this page helpful?
0 / 5 - 0 ratings