facebook / react-native

A framework for building native applications using React
https://reactnative.dev
MIT License
118.52k stars 24.27k forks source link

Failing unit tests involving jest.resetAllMocks and requiring some RN components from within mocks #42904

Open stevoland opened 8 months ago

stevoland commented 8 months ago

Description

Bit of a niche one: We see failing unit tests after upgrading 0.72.10 --> 0.73.4:

Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: undefined. You likely forgot to export your component from the file it's defined in, or you might have mixed up default and named imports.

    Check the render method of `ForwardRef(Switch)`.

Real-world manifestation occurs in tests calling jest.resetAllMocks() with a setup using v1 reanimated mock https://github.com/software-mansion/react-native-reanimated/blob/main/mock.js

Some info from debugging:

a) the mock requires Image from 'react-native' (among other things but Image causes the issue) b) the test calls jest.resetAllMocks() c) @testing-library/react-native renders Switch with react-test-renderer in each test which blows up here: https://github.com/callstack/react-native-testing-library/blob/main/src/helpers/host-component-names.tsx#L37

(There may be other (mocked) components affected by the issue)

See reduced test case in this commit https://github.com/stevoland/RNTest/commit/9841d46ce0c03cde9749c36ddd58a8b2bb96930a

Our workaround is to first get a reference to Switch in the setupFiles https://github.com/stevoland/RNTest/blob/9841d46ce0c03cde9749c36ddd58a8b2bb96930a/jest-setup.js#L2 (Possibly relevant that this has to be a require and not an import statement)

Thanks

Steps to reproduce

git clone https://github.com/stevoland/RNTest yarn install yarn test

React Native Version

0.73.4

Affected Platforms

Other (please specify)

Output of npx react-native info

info Fetching system and libraries information...
System:
  OS: macOS 14.1
  CPU: (12) arm64 Apple M2 Pro
  Memory: 99.78 MB / 32.00 GB
  Shell:
    version: 3.2.57
    path: /bin/bash
Binaries:
  Node:
    version: 18.18.0
    path: ~/.nvm/versions/node/v18.18.0/bin/node
  Yarn:
    version: 1.22.19
    path: ~/.nvm/versions/node/v18.18.0/bin/yarn
  npm:
    version: 9.8.1
    path: ~/.nvm/versions/node/v18.18.0/bin/npm
  Watchman:
    version: 2023.11.20.00
    path: /opt/homebrew/bin/watchman
Managers:
  CocoaPods:
    version: 1.11.3
    path: /usr/local/bin/pod
SDKs:
  iOS SDK:
    Platforms:
      - DriverKit 23.0
      - iOS 17.0
      - macOS 14.0
      - tvOS 17.0
      - watchOS 10.0
  Android SDK: Not Found
IDEs:
  Android Studio: 2021.1 AI-211.7628.21.2111.8309675
  Xcode:
    version: 15.0/15A240d
    path: /usr/bin/xcodebuild
Languages:
  Java:
    version: 15.0.1
    path: /usr/bin/javac
  Ruby:
    version: 2.6.10
    path: /usr/bin/ruby
npmPackages:
  "@react-native-community/cli": Not Found
  react:
    installed: 18.2.0
    wanted: 18.2.0
  react-native:
    installed: 0.73.4
    wanted: 0.73.4
  react-native-macos: Not Found
npmGlobalPackages:
  "*react-native*": Not Found
Android:
  hermesEnabled: true
  newArchEnabled: false
iOS:
  hermesEnabled: Not found
  newArchEnabled: false

Stacktrace or Logs

FAIL  __tests__/boom.test.tsx
  ● Console

    console.error
      Warning: React.jsx: type is invalid -- expected a string (for built-in components) or a class/function (for composite components) but got: undefined. You likely forgot to export your component from the file it's defined in, or you might have mixed up default and named imports.

      Check the render method of `ForwardRef(Switch)`.
          at disabled (/Users/stephen.collings/workspace/react-native-repro/RNTest/node_modules/react-native/Libraries/Components/Switch/Switch.js:141:5)

      16 |
      17 | it('doesnt blow up', () => {
    > 18 |   create(<Switch />);
         |         ^
      19 | });
      20 |

      at printWarning (node_modules/react/cjs/react-jsx-runtime.development.js:87:30)
      at error (node_modules/react/cjs/react-jsx-runtime.development.js:61:7)
      at jsxWithValidation (node_modules/react/cjs/react-jsx-runtime.development.js:1244:7)
      at jsxWithValidationDynamic (node_modules/react/cjs/react-jsx-runtime.development.js:1301:12)
      at Switch (node_modules/react-native/Libraries/Components/Switch/Switch.js:244:7)
      at renderWithHooks (node_modules/react-test-renderer/cjs/react-test-renderer.development.js:6351:18)
      at updateForwardRef (node_modules/react-test-renderer/cjs/react-test-renderer.development.js:9150:20)
      at beginWork (node_modules/react-test-renderer/cjs/react-test-renderer.development.js:11361:16)
      at performUnitOfWork (node_modules/react-test-renderer/cjs/react-test-renderer.development.js:15811:12)
      at workLoopSync (node_modules/react-test-renderer/cjs/react-test-renderer.development.js:15745:5)
      at renderRootSync (node_modules/react-test-renderer/cjs/react-test-renderer.development.js:15717:7)
      at performSyncWorkOnRoot (node_modules/react-test-renderer/cjs/react-test-renderer.development.js:15422:20)
      at flushSyncCallbacks (node_modules/react-test-renderer/cjs/react-test-renderer.development.js:2597:22)
      at flushSyncCallbacksOnlyInLegacyMode (node_modules/react-test-renderer/cjs/react-test-renderer.development.js:2576:5)
      at scheduleUpdateOnFiber (node_modules/react-test-renderer/cjs/react-test-renderer.development.js:14910:7)
      at updateContainer (node_modules/react-test-renderer/cjs/react-test-renderer.development.js:17770:5)
      at create (node_modules/react-test-renderer/cjs/react-test-renderer.development.js:18510:3)
      at Object.<anonymous> (__tests__/boom.test.tsx:18:9)

Reproducer

https://github.com/stevoland/RNTest/tree/jest-reset-switch-repro

Screenshots and Videos

No response

seanim0920 commented 7 months ago

Bump, seeing similar issues

anton-patrushev commented 5 months ago

Just experienced the same issue after upgrading react-native from 0.72.12 to 0.73.8

Here are some other versions I'm using. Hope it should help for the investigation

"@testing-library/jest-native": "5.4.3",
"@testing-library/react-hooks": "8.0.1",
"@testing-library/react-native": "12.4.4",
"babel-jest": "29.7.0",
"jest": "29.7.0",
"jest-environment-jsdom": "^29.7.0",
"jest-junit": "13.0.0",
"react-test-renderer": "18.2.0",
anton-patrushev commented 5 months ago

Just experienced the same issue after upgrading react-native from 0.72.12 to 0.73.8

Here are some other versions I'm using. Hope it should help for the investigation

"@testing-library/jest-native": "5.4.3",
"@testing-library/react-hooks": "8.0.1",
"@testing-library/react-native": "12.4.4",
"babel-jest": "29.7.0",
"jest": "29.7.0",
"jest-environment-jsdom": "^29.7.0",
"jest-junit": "13.0.0",
"react-test-renderer": "18.2.0",

I was able to fix this type of issue with migration jest.resetAllMocks to jest.clearAllMocks

citrocitrusyolo commented 1 month ago

I'm also running into this and greatly appreciate y'all mentioning the workaround of popping the below into the jest-setup.ts as that worked around it for us. Switching from reset to clear didn't make any difference for us though.

const { Switch } = require('react-native');

🙇