0

I'm trying to test custom hook that contains fetching api request

this is the code in useReportDownload.ts hook

import { useEffect, useState } from 'react'
import { useParams } from 'react-router'
import { fetchdownload } from '~/services'

export default function useReportDownload() {
  const { id } = useParams()
  const [list, setList] = useState<Array<any>>([])

  const getList = async () => {
    try {
      if (id) {
        const data = await fetchdownload(Number(id))
        setList(data)
      }
    } catch (error) {
      // eslint-disable-next-line no-console
      console.debug('error', error)
    }
  }

  useEffect(() => {
    getList()
  }, [id])

  return {
    list,
  }
}

this is the test file listreports.spec.tsx:

import { render, screen } from '@testing-library/react'
import { renderHook } from '@testing-library/react-hooks'
import { rest } from 'msw'
import { setupServer } from 'msw/node'
import '@testing-library/jest-dom/extend-expect'
import useReportDownload from './useReportDownload'
import ReportDownload from '.'

const data = [
  {
    id: '1',
    name: 'Test',
    url: 'https://test.com',
    actions: [
      {
        buttonType: 'icon',
        event: 'download',
        icon: 'download',
        label: 'Download',
      },
    ],
  },
  {
    id: '2',
    name: 'Test2',
    url: 'https://test2.com',
    actions: [
      {
        buttonType: 'icon',
        event: 'download',
        icon: 'download',
        label: 'Download',
      },
    ],
  },
]

const server = setupServer(
  rest.get('campaigns/1/proof-execution', async (req, res, ctx) =>
    res(ctx.json(data))
  )
)

beforeAll(() => server.listen())
afterEach(() => server.resetHandlers())
afterAll(() => server.close())

describe('useReportDownload', () => {
  it('should return the expected result', () => {
    const { result } = renderHook(() => useReportDownload())
    expect(result.current.list).toEqual([])
    expect(result.current.handleAction).toBeInstanceOf(Function)
    expect(result.current.handlePage).toBeInstanceOf(Function)
    expect(result.current.handleSelectedReports).toBeInstanceOf(Function)
    expect(result.current.handleSelectAllReports).toBeInstanceOf(Function)
    expect(result.current.selectedReports).toEqual([])
  })
  it('should return the expected result', async () => {
    render(<ReportDownload />)
    const text = await screen.findByText('Test')
    // eslint-disable-next-line no-console
    console.log(text)
  })
})

this is the listreports.tsx component that uses the above hook :

import React from 'react'
import { Box } from '@mui/material'
import useReportDownload from './useReportDownload'
import NoResults from '~/components/NoResults'
import { ReactComponent as NoResultsImage } from '~/images/noResults.svg'
import TableList from '~/TableList'
import { tableColumns } from '~/constants'
import * as Styled from '~/styles'
import { cosmosService } from '~/services/cosmos'
import { i18n } from '~/i18n'

interface Props {
  isHeaderBarAvailable?: boolean;
  headComponent?: React.ReactNode;
}

const ReportDownload = ({
  isHeaderBarAvailable = true,
  headComponent,
}: Props) => {
  const {
    list,
    handleAction,
    handlePage,
    handleSelectedReports,
    handleSelectAllReports,
    selectedReports,
  } = useReportDownload()

  const listContainer = () => (
    <>
      {list.length === 0 ? (
        <NoResults
          title={i18n.t('noResults.title')}
          description={i18n.t('noResults.description')}
          image={<NoResultsImage />}
        />
      ) : (
        <TableList
          enableCheckBox
          enableBulkSelect
          loading={false}
          columns={tableColumns}
          page={1}
          perPage={1}
          totalNumRows={list.length}
          enablePagination={false}
          rows={list}
          sortBy="id"
          orderBy="desc"
          selectedOptions={selectedReports}
          onCheckBoxChange={handleSelectedReports}
          onCheckBoxChangeAll={handleSelectAllReports}
          onPageChange={handlePage}
          onNumRowsChange={handlePage}
          onOrderChange={handlePage}
          onAction={handleAction}
        />
      )}
    </>
  )

  const fileComponent = () => (
    <Styled.Grid>
      <Styled.SelectedItemsBox>
        {i18n.t('reports.details.selectedItems')}
        <b>{selectedReports?.length}</b>
      </Styled.SelectedItemsBox>
      <Styled.Button
        onClick={() => cosmosService.downloadMedias(list, selectedReports)}
      >
        {i18n.t('reports.details.exportButton')}
      </Styled.Button>
    </Styled.Grid>
  )

  return (
    <Box>
      {headComponent}
      {isHeaderBarAvailable && <Box height="10%" />}
      {selectedReports?.length > 0 && fileComponent()}
      <Box height="100%">{listContainer()}</Box>
    </Box>
  )
}

export default ReportDownload

the problem is the mock data is not working, I want to test that when fetching data the list should have the data, but I have this error

✕ should return the expected result (1037 ms)

  ● useReportDownload › should return the expected result

    Unable to find an element with the text: Test. This could be because the text is broken up by multiple elements. In this case, you can provide a function for your text matcher to make your matcher more flexible.

    <body>
      <div>
        <div
          class="MuiBox-root css-0"
        >
          <div
            class="MuiBox-root css-1w5i5lh"
          />
          <div
            class="MuiBox-root css-10klw3m"
          >
            <div
              class="MuiBox-root css-32vdxk"
            >
              <div
                class="MuiBox-root css-24os1g"
              >
                <svg>
                  noResults.svg
                </svg>
              </div>
              <div
                class="MuiBox-root css-xi606m"
              >
                <p
                  class="MuiTypography-root MuiTypography-body1 css-eflgtu-MuiTypography-root"
                >
                  No Results
                </p>
                <p
                  class="MuiTypography-root MuiTypography-body1 css-66p3eu-MuiTypography-root"
                >
                  Your search has not returned any results
                </p>
              </div>
            </div>
          </div>
        </div>
      </div>
    </body>

      61 |   it('should return the expected result', async () => {
      62 |     render(<ReportDownload />)
    > 63 |     const text = await screen.findByText('Test')
         |                               ^
      64 |     // eslint-disable-next-line no-console
      65 |     console.log(text)
      66 |   })

      at waitForWrapper (node_modules/@testing-library/dom/dist/wait-for.js:173:27)
      at findByText (node_modules/@testing-library/dom/dist/query-helpers.js:101:33)
      at Object.<anonymous> (src/components/ReportDownload/UseReportDownload.spec.tsx:63:31)

Test Suites: 1 failed, 1 total
Tests:       1 failed, 1 passed, 2 total
Snapshots:   0 total
Time:        3.977 s, estimated 4 s

so what is wrong?

omar sobhy
  • 23
  • 3

0 Answers0