# [JEST] TEST
## React-router
### useNavigate
```jsx!
import * as router from 'react-router'
const navigate = jest.fn()
beforeEach(() => {
jest.spyOn(router, 'useNavigate').mockImplementation(() => navigate)
})
it('...', () => {
...
expect(navigate).toHaveBeenCalledWith('/path')
})
```
> <https://stackoverflow.com/a/72289488>
---
## toast
```typescript!
import { toast } from 'react-hot-toast'
jest.mock('react-hot-toast')
jest.spyOn(toast, 'promise').mockImplementation(promise => promise)
```
---
## SWR
```typescript!
jest
.spyOn(SWR, 'default')
.mockImplementation(() => ({ data: identifyProfile, isValidating: false, mutate: () => Promise.resolve() }));
```
>
> <https://stackoverflow.com/a/76376168>
>
> <https://jestjs.io/docs/jest-object#jestspyonobject-methodname>
>
---
### useSWR
```typescript!
import { useSWRConfig } from 'swr';
jest.mock('swr', () => ({
...jest.requireActual('swr'),
useSWRConfig: jest.fn(() => ({
mutate: () => {},
})),
}));
it('should mutate data', async () => {
const mockMutate = jest.fn();
useSWRConfig.mockImplementationOnce(() => ({ mutate: mockMutate }));
expect(mockMutate).toHaveBeenCalledWith('swrKey');
...
});
```
>
> <https://stackoverflow.com/a/76421717>
>
---
```typescript!
jest.mock("swr");
useSWRInfinite.mockReturnValue({ "data": [{ data: [] }], "error": null });
```
>
> <https://github.com/vercel/swr/discussions/711#discussioncomment-110076>
>
---
```typescript!
const mockedMutate = jest.fn();
jest.mock('swr', () => ({
__esModule: true,
...jest.requireActual('swr'),
useSWR: jest.fn(() => ({
mutate: () => mockedMutate,
})),
}));
fireEvent.click(disableUser);
await waitFor(() => {
expect(mockedMutate).toBeCalledTimes(10);
});
```
>
> <https://github.com/vercel/swr/discussions/2077#discussioncomment-6384044>
>
---
## Custom Hooks
>
> <https://engineering.mobalab.net/2022/12/13/test-react-custom-hooks-with-jest-and-testing-library/>
>
> <https://pjchender.dev/npm/npm-jest-tip/>
>
```typescript!
import { renderHook, act } from '@testing-library/react'
import { toast } from 'react-hot-toast'
import { useUploadFile } from './index'
jest.mock('react-hot-toast')
const mockUploadService = {
upload: jest.fn(),
}
jest.mock('@/service/upload', () => ({
useCreate: () => ({
trigger: mockUploadService.upload,
isMutating: false,
}),
}))
describe('useUploadFile', () => {
afterEach(() => {
jest.clearAllMocks()
})
it('should return correct hook values', () => {
const { result } = renderHook(() => useUploadFile())
expect(result.current).toHaveProperty('isMutating')
expect(result.current).toHaveProperty('handleUploadFile')
})
it('should not trigger upload when no file is selected', async () => {
const { result } = renderHook(() => useUploadFile())
const mockFileList = {
length: 0,
item: (_: number) => null,
}
await act(async () => {
await result.current.handleUploadFile(mockFileList as FileList)
})
expect(mockUploadService.upload).not.toHaveBeenCalled()
})
it('should trigger upload and return correct URL when file is selected', async () => {
const file = new File(['hello'], 'hello.txt', { type: 'text/plain' })
const url = 'https://example.com/hello.txt'
const mockResolvedValue = { url }
mockUploadService.upload.mockResolvedValueOnce(mockResolvedValue)
jest.spyOn(toast, 'promise').mockImplementation(promise => promise)
const { result } = renderHook(() => useUploadFile())
const mockFileList = {
0: file,
length: 1,
item: (_: number) => file
}
await act(async () => {
const uploadedUrl = await result.current.handleUploadFile(mockFileList as unknown as FileList)
expect(uploadedUrl).toBe(url)
expect(mockUploadService.upload).toHaveBeenCalledWith(expect.any(FormData))
expect(toast.promise).toHaveBeenCalled()
})
})
})
```
---
## React-hook-form
> <https://claritydev.net/blog/testing-react-hook-form-with-react-testing-library>
- have to install userEvent
```jsx!
import userEvent from "@testing-library/user-event";
```
>
> <https://codesandbox.io/p/sandbox/react-hook-form-reset-test-75qqh>
>
---
### useForm
> <https://github.com/orgs/react-hook-form/discussions/8303#discussioncomment-2687629>
> <https://github.com/orgs/react-hook-form/discussions/8061#discussioncomment-5906803>