I have a custom hook that downloads a file from an url, it works fine and now I trying to test its behaviour.
const useFileDownload = ({ apiResponse, fileName }) => {
const ref = useRef(null)
const [url, setUrl] = useState('')
const [name, setName] = useState('')
const download = async () => {
const { data } = await apiResponse()
const objectUrl = window.URL.createObjectURL(new Blob([data]))
setUrl(objectUrl)
setName(fileName)
ref.current?.click()
window.URL.revokeObjectURL(objectUrl)
}
return { url, ref, name, download }
}
I call like this on my component
const { ref, url, download, name } = useFileDownload({
apiResponse: () => axios.get(pdfUrl, { responseType: 'blob' }),
fileName: 'my_custom.pdf'
})
...
...
// this stay hidden on my component
<a href={url} download={name} ref={ref} />
And my test
describe('useFileDownload', () => {
it('should create refs', async () => {
window.URL.createObjectURL = jest.fn()
const mockRequest = jest.fn().mockResolvedValue({ data: 'url/to/pdf' })
const { result } = renderHook(() => useFileDownload({ apiResponse: mockRequest, fileName: 'sample.pdf' }))
act(() => {
result.current.download()
})
expect(result.current.name).toBe('sample.pdf')
expect(mockRequest).toBeCalledTimes(1)
})
})
I'm trying to mock createObjectURL, but it doesn't seem to work, and I don't know if its the right way. If the line containing window.URL fails, then the rest of the code fails on the assertion too.