I'm working on test cases with react testing library. To write the test case I need to mock the useQuery and useMutation method of react query. If anyone knows the solution please guide me. I'm adding the related code here.
WorkspaceDetailsSection.test.tsx
import React from 'react'
import '@testing-library/jest-dom'
import '@testing-library/jest-dom/extend-expect'
import { screen, waitFor } from '@testing-library/react'
import userEvent from '@testing-library/user-event'
import { WorkspaceDetailsSection } from '../WorkspaceDetailsSection'
import { render } from '../../_utils/test-utils/test-utils'
const mockedFunction = jest.fn()
let realUseContext: any
let useContextMock: any
// Setup mock
beforeEach(() => {
realUseContext = React.useContext
useContextMock = React.useContext = jest.fn()
})
// Cleanup mock
afterEach(() => {
React.useContext = realUseContext
})
jest.mock('../data', () => ({
useMutationHook: () => ({ mutate: mockedFunction })
}))
const WorkspaceContext = {
workspaceInfo: {
name: 'name',
dot: 'name',
type: 'type'
}
}
test('renders section with the valid details', async () => {
useContextMock.mockReturnValue(WorkspaceContext)
render(<WorkspaceDetailsSection />)
expect(screen.getByText('Workspace name:')).toBeInTheDocument()
})
WorkspaceDetailsSection.tsx
import React, { useContext } from 'react'
import { FormModal, useDisclosure } from '@chaine/keychaine'
import { workspaceService } from './data'
import { useMutation } from 'react-query'
import { Section } from '../account-settings'
import { Toast } from '../_shared/components'
import { IWorkspace } from '../_shared/refactoredInterfaces'
import constant from '../_shared/constants/message'
import { WorkspaceContext } from './WorkspacePage'
import capitalizeFirstLetter from '../_utils/capitalizeFirstLetter'
import { queryClient } from '../_shared/infra'
/**
*
* should import section component and return that
*/
export const WorkspaceDetailsSection = () => {
const { isOpen, onOpen, onClose } = useDisclosure()
const { workspaceInfo } = useContext(WorkspaceContext)
const { name, dot, type } = workspaceInfo
const { showToast } = Toast()
const updateWorkspace = useMutation((params: any) => workspaceService.updateWorkspace(params))
const handleSubmit = async (event: any) => {
const params: IWorkspace = {
...event,
id: workspaceInfo.id,
type: event.type.value
}
updateWorkspace.mutate(params, {
onSuccess: () => {
onClose()
queryClient.invalidateQueries('WorkspaceProfile')
},
onError: () => {
showToast({
title: constant.UNABLE_TO_UPDATE_WORKSPACE,
status: 'error'
})
}
})
}
return (
<>
<Section
sectionTitle={'Workspace details'}
multipleFields={[
{ fieldName: 'Workspace name:', value: name },
{ fieldName: 'Workspace type:', value: type },
{ fieldName: 'DOT #:', value: dot }
]}
buttonName={'Edit details'}
onClick={() => onOpen()}
/>
<FormModal
isOpen={isOpen}
onClose={() => onClose()}
title={'Change workspace info'}
size={'lg'}
formSubmitHandler={handleSubmit}
isLoading={updateWorkspace.isLoading}
initialValues={{
dot: dot,
type: { label: capitalizeFirstLetter(type), value: type },
name: name
}}
modalItems={[
{
name: 'name',
type: 'input',
placeHolder: 'Enter you name',
labelText: 'Workspace display name'
},
{ name: 'dot', type: 'input', placeHolder: 'Enter you DOT #', labelText: 'DOT #' },
{
name: 'type',
type: 'select',
placeHolder: type,
labelText: 'Workspace type',
selectOptions: [
{ label: 'Carrier', value: 'carrier' },
{ label: 'Broker', value: 'broker' },
{ label: 'Shipper', value: 'shipper' }
]
}
]}
/>
</>
)
}
WorkspaceService.ts
import { BaseAPI } from '../../_shared/infra/services/BaseAPI'
import { ITokenService, IWorkspace } from '../../_shared/refactoredInterfaces'
import { TeamResponseDTO, UpdateWorkspaceResponseDTO, UploadWorkspaceLogoResponseDTO } from './WorkspaceDTO'
export interface IWorkspaceService {
getWorkspace(): Promise<TeamResponseDTO>
updateWorkspace(params: IWorkspace): Promise<UpdateWorkspaceResponseDTO>
uploadWorkspaceLogo(params: any): Promise<UploadWorkspaceLogoResponseDTO>
}
export class WorkspaceService extends BaseAPI implements IWorkspaceService {
constructor(tokenService: ITokenService) {
super(tokenService)
}
async getWorkspace(): Promise<TeamResponseDTO> {
const body = {
url: '/users/account'
}
const { data } = await this.get(body)
return {
team: data?.data,
message: data?.message
}
}
async updateWorkspace(params: IWorkspace): Promise<UpdateWorkspaceResponseDTO> {
const body = {
url: '/accounts',
data: params
}
const { data } = await this.put(body)
return {
message: data.message
}
}
async uploadWorkspaceLogo(params: FormData): Promise<UploadWorkspaceLogoResponseDTO> {
const body = {
url: '/accounts/logos',
data: params,
headers: {
'Content-Type': 'multipart/form-data'
}
}
const response = await this.post(body)
return response
}
}
Also tried the solution proposed by @TkDodo here but did not work for me. The solution of this will be a life saver for me so thank you folks in advance.