testing-library/react-hooks-testing-library

Does `react-hooks-testing-library` support `React Native`, especially `Expo` ?

Toshiyuki023Hori opened this issue · 2 comments

Does react-hooks-testing-library support React Native, especially Expo ?

Thank you for checking at my problem.
I would like you to tell me whether we can test React Hooks in Expo.

package.json

  "dependencies": {
    "@react-navigation/bottom-tabs": "^6.3.1",
    "@react-navigation/native": "^6.0.10",
    "@react-navigation/native-stack": "^6.6.1",
    "@testing-library/react-hooks": "^8.0.0",
    "@testing-library/react-native": "^9.1.0",
    "@types/jest": "^27.5.0",
    "@types/react-test-renderer": "^18.0.0",
    "@types/testing-library__react-hooks": "^4.0.0",
    "babel-plugin-dotenv-import": "^2.2.0",
    "expo": "~44.0.0",
    "expo-location": "~14.0.1",
    "expo-permissions": "~13.1.0",
    "expo-status-bar": "~1.2.0",
    "jest": "^26.6.3",
    "jest-expo": "^44.0.1",
    "native-base": "^3.3.11",
    "prettier": "^2.6.2",
    "react": "17.0.1",
    "react-dom": "17.0.1",
    "react-native": "0.64.3",
    "react-native-maps": "0.29.4",
    "react-native-safe-area-context": "3.3.2",
    "react-native-screens": "~3.10.1",
    "react-native-svg": "12.1.1",
    "react-native-web": "0.17.1",
    "react-test-renderer": "^18.1.0",
    "tailwind-rn": "^4.2.0",
    "tailwindcss": "^3.0.23",
    "ts-node": "^10.7.0"
  },
  "devDependencies": {
    "@babel/core": "^7.12.9",
    "@types/react": "~17.0.21",
    "@types/react-native": "~0.64.12",
    "@typescript-eslint/eslint-plugin": "^5.18.0",
    "@typescript-eslint/parser": "^5.18.0",
    "babel-plugin-module-resolver": "^4.1.0",
    "concurrently": "^7.1.0",
    "eslint": "^8.13.0",
    "eslint-config-prettier": "^8.5.0",
    "eslint-plugin-react": "^7.29.4",
    "eslint-plugin-react-hooks": "^4.4.0",
    "npm-run-all": "^4.1.5",
    "postcss": "^8.4.12",
    "react-devtools": "^4.22.0",
    "typescript": "~4.3.5"
  },

jest.config.ts

import { Config } from '@jest/types'

const config: Config.InitialOptions = {
  preset: 'jest-expo',
  transformIgnorePatterns: [
    'node_modules/(?!((jest-)?react-native|@react-native(-community)?)|expo(nent)?|@expo(nent)?/.*|@expo-google-fonts/.*|react-navigation|@react-navigation/.*|@unimodules/.*|unimodules|sentry-expo|native-base|react-native-svg|native-base)',
  ],
    moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx'],
}

export default config

Custom Hook

import { useCallback, useState } from 'react';

export type UseCounterReturnType = {
  count: number;
  increment: () => void;
};

export const useCounter = (): UseCounterReturnType => {
  const [count, setCount] = useState(0);
  const increment = useCallback(() => setCount((n) => n + 1), []);
  return {
    count,
    increment,
  };
};

Test Code

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

describe('useCounter', () => {
  let result: HookResult<UseCounterReturnType>;
  beforeEach(() => {
    result = renderHook(() => useCounter()).result;
  });

  test('initial Value is 0', () => {
    expect(result.current.count).toBe(0);
  });

  test('Change count value', () => {
    expect(result.current.count).toBe(0);
    act(() => {
      result.current.increment();
    });
    expect(result.current.count).toBe(1);
  });
});

Test Result

 FAIL  src/hooks/useCounter.spec.ts
  useCounter
    ✕ initial Value is 0 (2 ms)
    ✕ Change count value

  ● useCounter › initial Value is 0

    TypeError: (0 , _reactTestRenderer.act) is not a function

      17 |       それらを使う場合はresultではなくrendrHookの返り値自体を格納するか別途受け取る変数を定義してやるといいでしょう
      18 |     */
    > 19 |     result = renderHook(() => useCounter()).result
         |              ^
      20 |   })
      21 |
      22 |   test('initial Value is 0', () => {

      at render (node_modules/@testing-library/react-hooks/lib/native/pure.js:73:34)
      at renderHook (node_modules/@testing-library/react-hooks/lib/core/index.js:114:5)
      at Object.<anonymous> (src/hooks/useCounter.spec.ts:19:14)

  ● useCounter › initial Value is 0

    TypeError: Cannot read properties of undefined (reading 'current')

      21 |
      22 |   test('initial Value is 0', () => {
    > 23 |     expect(result.current.count).toBe(0)
         |                   ^
      24 |   })
      25 |
      26 |   test('Change count value', () => {

      at Object.<anonymous> (src/hooks/useCounter.spec.ts:23:19)

Question

According to above errors, I guess we cannot use react-hooks-testing-library in Expo project.
If we can use the module, I would like you to tell me how to solve it.

Thank you very much.

This error is being caused by using react-test-renderer version 18 which react version 17. The version of these should match.

However, given you are just starting your hook tests, I suggest you use the new renderHook hook API in the latest version of @testing-library/react-native which is replacing this library for testing hooks in react-native and Expo going forward.

Closing due to inactivity