Reading request.formData with vitest

57 views Asked by At

I have this hook that posts with formData:

export function useTrackIngredientsViewed(
  productType: IngredientsViewedProductType
) {
  return (product: ShopifyPick) => {
    const formData = new FormData()
    formData.set('product', JSON.stringify(product))
    formData.set('type', productType)

    fetch('/actions/events/track-ingredients-viewed', {
      method: 'post',
      body: formData,
    })
  }
}

I've used this hook in my application and I know it works.

Now I'm trying to test the fetch request made by the hook. I want to get the form data, use Object.fromEntries(await request.formData()), and assert that it's equal to some data I pass it.

import createFetchMock from 'vitest-fetch-mock'
import { useTrackIngredientsViewed } from './useTrackIngredientsViewed'
import { testFactories } from '@shared/domain'

const fetchMocker = createFetchMock(vi)
fetchMocker.enableMocks()

describe('useTrackIngredientsViewed', () => {
  beforeAll(() => {
    fetchMocker.doMock()
  })
  beforeEach(() => fetchMocker.resetMocks())
  afterAll(() => fetchMocker.disableMocks())

  it('calls the endpoint with the correct data', async () => {
    const tracker = useTrackIngredientsViewed('deal')
    const product = testFactories.makeShopifyPick()
    tracker(product)
    const [req] = fetchMocker.requests()
    if (!req) throw Error('fetch was not called')

    const url = '/actions/events/track-ingredients-viewed'
    expect(req.url).toEqual(url)
    expect(req.method.toLowerCase()).toEqual('post')
    
    const reqProduct = Object.fromEntries(await req.formData())
    expect(reqProduct).toEqual(product)
  })
})

But req.formData is undefined! Other things I've tried:

  • req.body is ReadableStream
  • req.json() has an unexpected character and fails
  • await req.text() return [object FormData] (so I know the formData is in there somewhere!)
0

There are 0 answers