JavaScriptJestReact

Testing own custom React hook by using `@testing-library/react-hook` with Jest

Sometimes we create an own custom React hook for your own React application.And these hooks have a several fun […]

広告ここから
広告ここまで

Sometimes we create an own custom React hook for your own React application.
And these hooks have a several functionality like handling state and dispatching Redux action and moe…
We can test these hooks using @testing-library/react-hook.

Install

$ yarn add -D  react-@testing-library/react-hooks react-test-renderer

Write a test for React hook

In this post, we make a test code for the example custom hook.


const useExampleModalHook = () => {
    const [modal, modalOpen] = useState(false)
    const open = useCallback(() => {
      modalOpen(true)
    }, [modalOpen])
    const close = useCallback(() => {
      modalOpen(false)
    }, [modalOpen])
    const toggle = useCallback(() => {
      modalOpen(!modal)
    }, [modal, modalOpen])
    return {
      modal,
      open,
      close,
      toggle,
    }
  }

And this is a test code for the hook.

import { renderHook, act } from '@testing-library/react-hooks';

describe('useExampleModalHook', () => {
  let result = renderHook(() => useExampleModalHook()).result
  beforeEach(() => {
    result = renderHook(() => useExampleModalHook()).result
  })
  afterEach(() => {
    mockDispatch.mockClear();
  });
  it('should modal is false by default', () => {
    expect(result.current.modal).toEqual(false)
  })
  it('should modal is true when call open', () => {
    act(() => {
      result.current.open()
    })
    expect(result.current.modal).toEqual(true)
  })
  it('should modal is true when called toggle once', () => {
    act(() => {
      result.current.toggle()
    })
    expect(result.current.modal).toEqual(true)
  })
  it('should modal is true when called toggle once', () => {
    act(() => {
      result.current.toggle()
    })
    act(() => {
      result.current.toggle()
    })
    expect(result.current.modal).toEqual(false)
  })
})

renderHook will return own hook without creating any React Component.

And use act, we can execute any hook function.

With Redux (useDispatch / useSelector)

If we want to test hook using Redux hooks, we need to mock by jest.

export const exampleHookWithRedux = () => {
  const dispatch = useDispatch();
  const globalClose = useCallback(() => {
    dispatch(closeUserModal('username'));
  }, [dispatch]);
  return {
    dummy: useSelector((state: State) => state.modal),
    globalClose,
  }
}

This is a test code for the hook.

const mockDispatch = jest.fn();
const mockSelector = jest.fn().mockImplementation(() => ({
  status: '',
  result: '',
}));
jest.mock('react-redux', () => ({
  useDispatch: () => mockDispatch,
  useSelector: () => mockSelector(),
}));


describe('exampleHookWithRedux ', () => {
  let result = renderHook(() => exampleHookWithRedux ()).result
  beforeEach(() => {
    result = renderHook(() => exampleHookWithRedux ()).result
  })
  it('should modal is false by default', () => {
    expect(result.current.dummy).toEqual({
      status: '',
      result: '',
    })
  })
  it('should call dispatch function at once', () => {
    act(() => {
      result.current.globalClose()
    })
    expect(mockDispatch).toHaveBeenCalledTimes(1)
  })
  it('should call valid action', () => {
    act(() => {
      result.current.globalClose()
    })
    expect(mockDispatch).toHaveBeenCalledWith({
      type: 'CLOSE_USER_MODAL',
      payload: {
        username: 'username'
      }
    })
  })
  it('When selector return updated value, should get updated one', () => {
    mockSelector.mockImplementationOnce(() => ({
      status: 'loading',
      result: ''
    }))
    result = renderHook(() => exampleHookWithRedux ()).result
    expect(result.current.dummy).toEqual({
      status: 'loading',
      result: '',
    })
  })
})

ブックマークや限定記事(予定)など

WP Kyotoサポーター募集中

WordPressやフロントエンドアプリのホスティング、Algolia・AWSなどのサービス利用料を支援する「WP Kyotoサポーター」を募集しています。
月額または年額の有料プランを契約すると、ブックマーク機能などのサポーター限定機能がご利用いただけます。

14日間のトライアルも用意しておりますので、「このサイトよく見るな」という方はぜひご検討ください。

広告ここから
広告ここまで

Related Category posts