How to write spyOn custom hook

3.6k Views Asked by At

I have a custom hook

import { useDispatch } from 'react-redux';
import { SET_APP_TITLE } from '../reducers/appBar';

export const useTitle = (title: string) => {
  const dispatch = useDispatch();
  return dispatch({ type: SET_APP_TITLE, title });
};

And component using it

import { useTitle } from '../common/useTitle';
export default () => {
  useTitle('Dashboard');
  return <div>Dashboard</div>
}

Now I want to write unit test (using Jest and React Testing Library) for the component:

import React from 'react';
import { render } from '@testing-library/react';
import Dashboard from './Dashboard';
import { useTitle } from '../commons/useTitle';

describe('Dashboard', () => {
  it('renders without crashing', () => {
    const { getByText } = render(<Dashboard />);
    expect(getByText('Dashboard')).toBeInTheDocument();
  });
});

In this test I'd like to spy on my custom hook and assert that the component tries to set valid title.

1

There are 1 best solutions below

0
On BEST ANSWER

Use jest.mock(moduleName, factory, options) to mock ../commons/useTitle module. The useTitle custom hook will be mocked when you import and use it in your test file.

E.g.

useTitle.ts:

import { useDispatch } from 'react-redux';

const SET_APP_TITLE = 'SET_APP_TITLE';

export const useTitle = (title: string) => {
  const dispatch = useDispatch();
  return dispatch({ type: SET_APP_TITLE, title });
};

Dashboard.tsx:

import React from 'react';
import { useTitle } from './useTitle';

export default () => {
  useTitle('Dashboard');
  return <div>Dashboard</div>;
};

Dashboard.test.tsx:

import '@testing-library/jest-dom/extend-expect';
import React from 'react';
import { render } from '@testing-library/react';
import Dashboard from './Dashboard';
import { useTitle } from './useTitle';

jest.mock('./useTitle');

describe('Dashboard', () => {
  it('renders without crashing', () => {
    const { getByText } = render(<Dashboard />);
    expect(getByText('Dashboard')).toBeInTheDocument();
    expect(jest.isMockFunction(useTitle)).toBeTruthy();
    expect(useTitle).toBeCalledWith('Dashboard');
  });
});

unit test result with coverage report:

 PASS  src/stackoverflow/64228834/Dashboard.test.tsx (17.901s)
  Dashboard
    ✓ renders without crashing (43ms)

---------------|----------|----------|----------|----------|-------------------|
File           |  % Stmts | % Branch |  % Funcs |  % Lines | Uncovered Line #s |
---------------|----------|----------|----------|----------|-------------------|
All files      |       80 |      100 |       50 |       80 |                   |
 Dashboard.tsx |      100 |      100 |      100 |      100 |                   |
 useTitle.ts   |       60 |      100 |        0 |       60 |               6,7 |
---------------|----------|----------|----------|----------|-------------------|
Test Suites: 1 passed, 1 total
Tests:       1 passed, 1 total
Snapshots:   0 total
Time:        19.534s, estimated 20s