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?