testing-library / native-testing-library

🐳 Simple and complete React Native testing utilities that encourage good testing practices.
https://native-testing-library.com
MIT License
516 stars 44 forks source link

Cannot convert undefined or null to object at assign (<anonymous>) #126

Closed alexwasner closed 4 years ago

alexwasner commented 4 years ago

Relevant code or config:

Repo with steps to reproduce

What you did:

Upon upgrading from React Native 0.62.2 to React Native 0.63.0-rc.1 (to pre-empt the upcoming release,) all of my tests broke.

What happened:

 FAIL  __tests__/App.test.tsx
  ✕ renders correctly (367 ms)

  ● renders correctly

    TypeError: Cannot convert undefined or null to object
        at assign (<anonymous>)

      at node_modules/@testing-library/react-native/dist/preset/mock-modules.js:41:3
      at Object.<anonymous> (node_modules/react-native/Libraries/Animated/src/AnimatedEvent.js:15:21)
      at Object.<anonymous> (node_modules/react-native/Libraries/Animated/src/AnimatedImplementation.js:14:44)

The stack trace differs based on the component, but it is always Cannot convert undefined or null to object

Reproduction:

Clone this repo and run the tests.

If you change the jest.config.js to

  preset: 'react-native',
  setupFilesAfterEnv: ['@testing-library/jest-native/extend-expect'],

the issue error is resolved

Problem description:

Tests fail. 🤷‍♂️

Suggested solution:

Can't dig into it too much atm

Can you help us fix this issue by submitting a pull request?

I'd love to, but other priorities with work.

hyochan commented 4 years ago

This holds us back on upgrading our project.

callumbooth commented 4 years ago

This is holding us back upgrading too

nelsonchen5 commented 4 years ago

+1

artdent commented 4 years ago

I haven't investigated what would fix it, but based on the stacktrace, I think the react-native commit that caused the breakage is https://github.com/facebook/react-native/commit/6e3389c82b6899ee3a9162571f7c6f8eab830207, which is an import of https://github.com/facebook/react/commit/2d6be757df86177ca8590bf7c361d6c910640895 from react. That commit removed the NativeMethodsMixin export referenced at https://github.com/testing-library/native-testing-library/blob/master/src/preset/mock-modules.js#L38.

mym0404 commented 4 years ago

I explored RN library code in react-native/Libraries/Renderer/shims/ReactNative. The problem is src/preset/mock-modules.js in this library.

// Re-mock ReactNative with native methods mocked
jest
  .mock('react-native/Libraries/Animated/src/NativeAnimatedHelper')
  .doMock('react-native/Libraries/Renderer/shims/ReactNative', () => {
    const ReactNative = jest.requireActual('react-native/Libraries/Renderer/shims/ReactNative');
    const NativeMethodsMixin =
      ReactNative.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED.NativeMethodsMixin;

    Object.assign(NativeMethodsMixin, mockNativeMethods);
    Object.assign(ReactNative.NativeComponent.prototype, mockNativeMethods);

    return ReactNative;
  });

The fields of NativeMethodMixin is changed since 0.63.

This seems to the adaption processing of the new React fiber.

alexbrazier commented 4 years ago

@TheSavior, any ideas what can be used instead here? Looks like it was this PR that removed this functionality https://github.com/facebook/react/pull/18036

elicwhite commented 4 years ago

Based on @mym0404's comment, that mock for ReactNative is trying to override NativeMethodsMixin and ReactNative.NativeComponent. Those don't exist anymore, I think you can delete that entire mock and just have the snippet above be:

jest
  .mock('react-native/Libraries/Animated/src/NativeAnimatedHelper');
mym0404 commented 4 years ago

@TheSavior The native methods of component like scrollTo or measure have been mocked with this library. But after remove mocking NativeComponent, we are facing issue like the following.

 TypeError: _scrollView$current.scrollTo is not a function

      51 | 
      52 |   const onTabChanged = (index: number) => {
    > 53 |     scrollView.current?.scrollTo({ x: pageWidth * index });
         |                         ^
      54 |     setPageIndex(index);
      55 |   };
      56 | 

      at Object.onTabChanged (src/components/shared/ViewPager/ViewPager.tsx:53:25)
      at Object.selectTab (src/components/shared/ViewPager/TabLayout.tsx:77:15)
      at NativeTestEvent.onMomentumScrollEnd [as _target] (src/components/shared/ViewPager/ViewPager.tsx:60:52)
      at fireEvent (node_modules/@testing-library/react-native/dist/lib/events.js:167:34)
      at Function.fireEvent.<computed> [as momentumScrollEnd] (node_modules/@testing-library/react-native/dist/lib/events.js:191:12)
      at node_modules/@testing-library/react-native/dist/index.js:206:45
      at batchedUpdates (node_modules/react-test-renderer/cjs/react-test-renderer.development.js:12395:12)
      at act (node_modules/react-test-renderer/cjs/react-test-renderer.development.js:14936:14)
      at Function.fireEvent.<computed> [as momentumScrollEnd] (node_modules/@testing-library/react-native/dist/index.js:205:28)
      at Object.<anonymous> (src/components/screen/MainDrawer/DemoTestList/DemoTestList.test.tsx:145:13)
elicwhite commented 4 years ago

I'd recommend looking at how those components with native methods, like ScrollView, is mocked in core: https://github.com/facebook/react-native/blob/master/jest/setup.js#L133-L152

mym0404 commented 4 years ago
  1. I removed redundant parts of mocking code in this library following your first suggestion

  2. I copied some mocking files at your link including mockComponent, MockNativeMethods, mockScrollView and mocking ScrollView of React Native.

    It works like a charm. Thank you :). my project is upgraded to 0.63 successfully.

image

daveols commented 4 years ago

I've fixed this in #136 🎉

aryella-lacerda commented 4 years ago

Awaiting new release to update our project 👍

daveols commented 4 years ago

You can now upgrade to version 6.0.0 for these fixes! 🚀