react-native-keyboard-aware-scroll-view icon indicating copy to clipboard operation
react-native-keyboard-aware-scroll-view copied to clipboard

TypeError: Cannot read property 'major' of undefined - when upgrading 0.9.3 → 0.9.4 - using Jest, react-native-testing-library

Open louiechristie opened this issue 3 years ago • 10 comments

When running upgrading react-native-keyboard-aware-scroll-view ^0.9.3 → ^0.9.4

by using

npx npm-check-updates --doctor -u

I get Jest with react-native-testing-library testing error:

    TypeError: Cannot read property 'major' of undefined

      at Object.extractNativeRef (node_modules/react-native-keyboard-aware-scroll-view/lib/KeyboardAwareHOC.js:135:93)
      at _this._handleRef (node_modules/react-native-keyboard-aware-scroll-view/lib/KeyboardAwareHOC.js:490:52)
      at commitAttachRef (node_modules/react-test-renderer/cjs/react-test-renderer.development.js:11992:7)
      at commitLayoutEffects (node_modules/react-test-renderer/cjs/react-test-renderer.development.js:14448:9)
      at Object.invokeGuardedCallbackProd (node_modules/react-test-renderer/cjs/react-test-renderer.development.js:11308:10)
      at invokeGuardedCallback (node_modules/react-test-renderer/cjs/react-test-renderer.development.js:11499:31)
      at commitRootImpl (node_modules/react-test-renderer/cjs/react-test-renderer.development.js:14172:9)
      at unstable_runWithPriority (node_modules/react-test-renderer/node_modules/scheduler/cjs/scheduler.development.js:468:12)
      at runWithPriority (node_modules/react-test-renderer/cjs/react-test-renderer.development.js:2486:10)
      at commitRoot (node_modules/react-test-renderer/cjs/react-test-renderer.development.js:14011:3)

Workaround

Use the built in KeyboardAvoidingView, and ScrollView from React Native

// TypeScript example 😬
import React from 'react';
import { KeyboardAvoidingView, ScrollView, KeyboardAvoidingViewProps } from 'react-native';

type Props = KeyboardAvoidingViewProps & { children: React.ReactNode };

const KeyboardAwareScrollView = (props: Props): JSX.Element => {
  const { children } = props;

  return (
    <KeyboardAvoidingView style={{ flex: 1 }} {...props}>
      <ScrollView contentContainerStyle={{ flexGrow: 1 }}>{children}</ScrollView>
    </KeyboardAvoidingView>
  );
};

export default KeyboardAwareScrollView;

Inspired by this post by pepperedpopcorn on Reddit

louiechristie avatar Jun 10 '21 08:06 louiechristie

I resolve this problem adding before the describe this: jest.mock('react-native-keyboard-aware-scroll-view');, but with this change I don't have access the childrens of component

salomaoluiz avatar Jun 15 '21 17:06 salomaoluiz

You can mock with access to childrens with this way: image

salomaoluiz avatar Jun 15 '21 17:06 salomaoluiz

Another workaround I found below is similar but it mocks it with KeyboardAwareScrollView

https://stackoverflow.com/questions/56333004/nativebase-content-not-rendered-in-jest-with-react-native-testing-library

@salomaoluiz, do you think there might be pros and cons to using KeyboardAwareScrollView instead of mockImplementation?

scottschulte-bh avatar Jun 17 '21 17:06 scottschulte-bh

FYI: I was having problems with the KeyboardAwareFlatList.

My workaround:

import { FlatList } from 'react-native';
jest.mock('react-native-keyboard-aware-scroll-view', () => {
  const KeyboardAwareScrollView = ({ children }) => children;
  const KeyboardAwareFlatList = FlatList;
  return { KeyboardAwareScrollView, KeyboardAwareFlatList };
});

williamgurzoni avatar Jul 21 '21 04:07 williamgurzoni

I solved this a little different:

jest.mock('react-native/Libraries/Utilities/Platform', () => {
	const platform = jest.requireActual('react-native/Libraries/Utilities/Platform');
	return {
		...platform,
		constants: {
			...platform.constants,
			reactNativeVersion: {
				major: 0,
				minor: 65,
				patch: 1,
			}
		},
	};
});

lucipacurar avatar Oct 08 '21 12:10 lucipacurar

I solved this a little different:

jest.mock('react-native/Libraries/Utilities/Platform', () => {
	const platform = jest.requireActual('react-native/Libraries/Utilities/Platform');
	return {
		...platform,
		constants: {
			...platform.constants,
			reactNativeVersion: {
				major: 0,
				minor: 65,
				patch: 1,
			}
		},
	};
});

It works for me, thanks a lot!! How did you get to this solution?

lailton-b avatar Jan 03 '22 16:01 lailton-b

I am using expo and to get RN version I adapted @lucipacurar code.

jest.mock('react-native/Libraries/Utilities/Platform', () => {
  const fs = require('fs')
  const json = JSON.parse(fs.readFileSync('node_modules/react-native/package.json', 'utf8'))
  const platform = jest.requireActual('react-native/Libraries/Utilities/Platform');
  const version = json.version.toString().split('.')
  return {
    ...platform,
    constants: {
      ...platform.constants,
      reactNativeVersion: {
        major: version[0],
        minor: version[1],
        patch: version[2],
      }
    },
  };
});

hasansna avatar Jan 15 '22 17:01 hasansna

Here's a mock that swaps out KeyboardAwareScrollView with a ScrollView to avoid massive diffs in your jest snapshots compared to using ({ children }) => children

jest.mock('react-native-keyboard-aware-scroll-view', () => {
  const KeyboardAwareScrollView = require('react-native').ScrollView;
  return { KeyboardAwareScrollView };
});

owjsub avatar Jan 27 '22 19:01 owjsub

jest.mock("react-native-keyboard-aware-scroll-view", () => {
  return {
    KeyboardAwareScrollView: (props: { children: React.ReactNode }) =>
      props.children,
  };
});

Solution provided by @salomaoluiz worked too 🙌

Snopkowski avatar Sep 01 '22 11:09 Snopkowski

I solved this a little different:

jest.mock('react-native/Libraries/Utilities/Platform', () => {
	const platform = jest.requireActual('react-native/Libraries/Utilities/Platform');
	return {
		...platform,
		constants: {
			...platform.constants,
			reactNativeVersion: {
				major: 0,
				minor: 65,
				patch: 1,
			}
		},
	};
});

This solution conflicts with

import mockSafeAreaContext from 'react-native-safe-area-context/jest/mock'
jest.mock('react-native-safe-area-context', () => mockSafeAreaContext)

Thus I strongly discourage it.

rarenatoe avatar Jul 27 '23 18:07 rarenatoe