Skip to content

React.createElement: type is invalid -- expected a string (for built-in components) or a class/function (for composite components) but got: undefined. #1678

@memon07

Description

@memon07

I have been facing two issues mainly

console.error
Warning: React.createElement: 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.

  19 |
  20 | test('renders the Example component and simulates a button press', () => {
> 21 |   const {getByTestId, getByText} = render(<Example />);
  22 |   // Check if the Text with the testID is rendered correctly
  23 |   const printedUsername = getByTestId('printed-username');

  at printWarning (node_modules/react/cjs/react.development.js:209:30)
  at error (node_modules/react/cjs/react.development.js:183:7)
  at Object.createElementWithValidation [as createElement] (node_modules/react/cjs/react.development.js:2354:7)
  at createElement (node_modules/@testing-library/react-native/src/helpers/host-component-names.tsx:35:9)
  at detectHostComponentNames (node_modules/@testing-library/react-native/src/helpers/host-component-names.tsx:27:30)
  at renderInternal (node_modules/@testing-library/react-native/src/render.tsx:48:40)
  at renderInternal (node_modules/@testing-library/react-native/src/render.tsx:29:10)
  at Object.<anonymous> (__tests__/Example1.js:20:42)

and sometimes i get this too

 FAIL  __tests__/Example1.js
  ● Test suite failed to run

  ReferenceError: expect is not defined

It seems possibly that render and expect from testing library are not properly set. i have tried a couple of fixes but noting seems to work.

can you please help me find the issue in my setup.

jest.setup.js

import 'react-native';
import React from 'react';
import 'react-native-gesture-handler/jestSetup';
import '@testing-library/react-native/extend-expect'; 

jest.mock('react-native-bootsplash', () => ({
  hide: jest.fn(),
  show: jest.fn(),
}));

jest.mock('@react-native-firebase/messaging', () => ({
   onMessage: jest.fn(),
   getToken: jest.fn(),
}));


jest.mock('react-native-encrypted-storage', () => ({
    setItem: jest.fn(),
    getItem: jest.fn(),
    removeItem: jest.fn(),
    clear: jest.fn(() => Promise.resolve()),
}));

    jest.mock('react-native-event-bus', () => ({
        getInstance: jest.fn(),
        on: jest.fn(),
        off: jest.fn(),
        emit: jest.fn(),
    }));
    
    jest.mock('react-native-device-info', () => ({
        getUniqueId: jest.fn(() => 'unique-id-mock'),
        getDeviceId: jest.fn(() => 'device-id-mock'),
        getVersion: jest.fn(() => '1.0.0'),
    }));
    
    jest.mock('react-native-flipper', () => ({
        addPlugin: jest.fn(),
        start: jest.fn(),
    }));
    
    jest.mock('@react-navigation/native', () => ({
        ...jest.requireActual('@react-navigation/native'),
        useNavigation: () => ({
          navigate: jest.fn(),
        }),
        NavigationContainer: ({ children }) => children,
    }));
    
    jest.mock('react-native-version-check', () => ({
        getLatestVersion: jest.fn().mockResolvedValue('1.0.0'),
        getCurrentVersion: jest.fn().mockReturnValue('1.0.0'),
        needUpdate: jest.fn().mockResolvedValue({
          isNeeded: false,
          storeUrl: 'https://appstore.example.com',
        }),
    }));
    
    
      
    jest.mock('@react-navigation/stack', () => {
        return {
            createStackNavigator: () => {
            return {
                Navigator: ({ children }) => children,
                Screen: () => null,
            };
            },
        };
    });
    
    jest.mock('react-native-gesture-handler', () => {
        const React = require('react');
        const { View, Text, TextInput,ScrollView,TouchableOpacity } = require('react-native');
      
        return {
          RNGestureHandlerRootView: View,
          TouchableWithoutFeedback: View,
          // Mock TextInput if you're using it
          TextInput: (props) => <TextInput {...props} />,
          ScrollView: (props) => <ScrollView {...props} />,
          TouchableOpacity: (props) => <TouchableOpacity {...props} />,
        };
      });
    
    jest.mock('@react-native-firebase/analytics', () => {
        return {
            logEvent: jest.fn(),
            setCurrentScreen: jest.fn(),
            setUserId: jest.fn(),
            setUserProperties: jest.fn(),
        };
    });
    
    jest.mock('react-native-animatable', () => {
        const View = require('react-native').View;
        return {
          View: View,
          Text: View,
          createAnimatableComponent: (Component) => Component,
          fadeIn: jest.fn(),
          fadeOut: jest.fn(),
          bounceIn: jest.fn(),
          bounceOut: jest.fn(),
        };
    });
      
    jest.mock('react-native-modal', () => {
        const React = require('react');
        const View = require('react-native').View;
        return ({ children, ...props }) => (
            <View {...props}>{children}</View>
        );
    });
    
    jest.mock('react-native-toast-message', () => {
        const React = require('react');
        const View = require('react-native').View;
        return {
          show: jest.fn(),
          hide: jest.fn(),
          Toast: (props) => <View {...props} />,
          BaseToast: (props) => <View {...props} />,
          ErrorToast: (props) => <View {...props} />,
          InfoToast: (props) => <View {...props} />,
          SuccessToast: (props) => <View {...props} />,
        };
    });
      
    jest.mock('react-native-biometrics', () => {
        return {
          BiometryTypes: {
            TouchID: 'TouchID',
            FaceID: 'FaceID',
            Biometrics: 'Biometrics',
          },
          isSensorAvailable: jest.fn(() => Promise.resolve({ available: true, biometryType: 'Biometrics' })),
          createKeys: jest.fn(() => Promise.resolve({ publicKey: 'mocked-public-key' })),
          createSignature: jest.fn(() => Promise.resolve({ success: true, signature: 'mocked-signature' })),
          simplePrompt: jest.fn(() => Promise.resolve({ success: true })),
        };
    });
    
    jest.mock('react-native-phone-number-input', () => {
        const React = require('react');
        const { View, TextInput } = require('react-native');
      
        const PhoneInput = (props) => {
          return (
            <View>
              <TextInput
                testID="phone-input"
                value={props.value}
                onChangeText={props.onChangeText}
                placeholder="Enter phone number"
              />
            </View>
          );
        };
      
        return PhoneInput;
    });
    
    jest.mock('react-native', () => {
        const actualReactNative = jest.requireActual('react-native');
      
        return {
          ...actualReactNative,
          requireNativeComponent: jest.fn((name) => {
            // Return a mock component based on the name
            if (name === 'SkeletonPlaceholder') {
              return jest.fn(); // Return a mock function for SkeletonPlaceholder
            }
            return jest.fn(); // For other components, return a simple mock function
          }),
        };
    });
    
    jest.mock('react-native-skeleton-placeholder', () => {
        return {
            __esModule: true,
            default: (props) => <div {...props} />, // Mock implementation
        };
    });
    
    jest.mock('react-native-snap-carousel', () => {
        return {
          Carousel: (props) => <div {...props} />, // Mock implementation
        };
    });
    
    jest.mock('react-native-image-slider-box', () => {
        return {
          SliderBox: (props) => <div {...props} />, // Mock implementation
        };
    });
    
    jest.mock('react-native-vector-icons/AntDesign', () => {
        return {
            __esModule: true, // If you are using ES6 imports
            default: () => null, // Mock implementation
        };
    });
    
    jest.mock('@sentry/react-native', () => ({
        captureException: jest.fn(),
        withScope: jest.fn(),
        init: jest.fn(),
        wrap: jest.fn((component) => component),
    }));
    
    jest.mock('@notifee/react-native', () => ({
        EventType: {
          ACTION_PRESS: 'ACTION_PRESS',
          DELIVERED: 'DELIVERED',
        },
        onForegroundEvent: jest.fn(),
        displayNotification: jest.fn(),
        cancelNotification: jest.fn(),
    }));
    
    jest.mock('react-native-push-notification', () => ({
        configure: jest.fn(),
        localNotification: jest.fn(),
        requestPermissions: jest.fn(),
        checkPermissions: jest.fn(),
        cancelAllLocalNotifications: jest.fn(),
    }));
    
    jest.mock('react-native', () => {
      const RN = jest.requireActual('react-native');
    
      return {
        ...RN,
        Platform: {
          ...RN.Platform,
          OS: 'ios', // or 'android', depending on your needs
          select: (obj) => obj['ios'], // or 'android' as needed
        },
      };
    });
    
    jest.mock('react-native', () => {
        const RN = jest.requireActual('react-native');
      
        return {
          ...RN,
          Platform: {
            ...RN.Platform,
            OS: 'android', // or 'android', depending on your needs
            select: (obj) => obj['android'], // or 'android' as needed
          },
        };
    });
    
    jest.mock('react-native-android-open-settings', () => ({
        RNAndroidOpenSettings: {
          openSettings: jest.fn(), // You can mock the methods you need
        },
    }));
    
    jest.mock('react-native-maps', () => {
        const React = require('react');
        const { View } = require('react-native');
      
        const MockMapView = (props) => {
          return React.createElement(View, props, props.children);
        };
      
        const MockMarker = (props) => {
          return React.createElement(View, props, props.children);
        };
      
        return {
          __esModule: true,
          default: MockMapView,
          Marker: MockMarker,
        };
    });
    
    jest.mock('react-native-gifted-chat', () => {
        return {
          GiftedChat: jest.fn((props) => <div {...props} />), // Mock the GiftedChat component
          Bubble: jest.fn((props) => <div {...props} />), // Mock the Bubble component
          Day: jest.fn((props) => <div {...props} />), // Mock the Day component
        };
    });
    
    jest.mock('react-native-code-push', () => {
        const cp = (_) => (app) => app;
        Object.assign(cp, {
          InstallMode: {},
          CheckFrequency: {},
          SyncStatus: {},
          UpdateState: {},
          DeploymentStatus: {},
          DEFAULT_UPDATE_DIALOG: {},
      
          checkForUpdate: jest.fn(),
          codePushify: jest.fn(),
          getConfiguration: jest.fn(),
          getCurrentPackage: jest.fn(),
          getUpdateMetadata: jest.fn(),
          log: jest.fn(),
          notifyAppReady: jest.fn(),
          notifyApplicationReady: jest.fn(),
          sync: jest.fn(),
        });
        return cp;
    });
    
    jest.mock('@sentry/react-native', () => ({
        init: jest.fn(),
        ReactNavigationInstrumentation: jest.fn(),
        ReactNativeTracing: jest.fn(),
        wrap: jest.fn((component) => component),
        TouchEventBoundary: ({ children }) => children,
    }));
    
    jest.mock('react-native/Libraries/Components/StatusBar/StatusBar', () => 'StatusBar');
    
    jest.mock('react-native/Libraries/Animated/NativeAnimatedHelper');
    
    jest.mock('react-native-keychain');  // Ensures Keychain is mocked
    
    jest.mock('react-native-webview');
    
    jest.mock('react-native');
    
    jest.mock('react-native-confirmation-code-field');
    
    jest.mock('react-native-document-picker');
    
    jest.mock('react-native-image-picker');
    
    jest.mock('react-native-permissions');
    
    jest.mock('react-native-recaptcha-that-works');
    
    jest.mock('react-native-file-viewer');
    
    jest.mock('react-native-image-zoom-viewer');
    
    jest.mock('rn-fetch-blob');
    
    jest.mock('react-native-parsed-text');
    
    jest.mock('react-native-restart');
    
    jest.mock('react-native-wheel-picker-android');
    
    jest.mock('@react-navigation/stack');
    
    jest.mock('@react-navigation/bottom-tabs');
    
    jest.mock('@ptomasroos/react-native-multi-slider');
    
    jest.mock('react-native-vector-icons');
    
    jest.mock('react-native-rsa-native');
    
    jest.mock('react-native-dropdown-picker');
    
    jest.mock('lottie-react-native');
    
    jest.mock('react-native-splash-screen');
    
    jest.mock('@react-native-community/netinfo');
    
    jest.mock('react-native/Libraries/TurboModule/TurboModuleRegistry', () => ({
        get: jest.fn(() => null),
        getEnforcing: jest.fn(() => ({})),
    }));
    
    jest.mock('./src/navigation/NavStack', () => 'NavStack');
    jest.mock('i18n-js'); 
    jest.mock('react-native-localize'); 

jest.config.js

module.exports = {
preset: 'react-native',
setupFilesAfterEnv: ["./jest.setup"],
transformIgnorePatterns: [
      'node_modules/(?!(react-native|@react-native|i18n-js|@react-navigation|react- 
      native-keychain|@react-native-firebase|react-native-polyfills|react-native- 
      config|react-native-encrypted-storage|react-native-version-check|react-native- 
      device-info|react-native-flipper|redux-flipper|react-native-modal|react-native- 
      toast-message|@react-native|react-native-gesture-handler|react-native- 
      animatable|react-native-biometrics|react-native-phone-number-input|react- 
      native-confirmation-code-field|react-native-webview|react-native-document- 
      picker|react-native-image-picker|react-native-permissions|react-native- 
      recaptcha-that-works|react-native-file-viewer|react-native-image-zoom- 
      viewer|rn-fetch-blob|react-native-parsed-text|react-native-restart|react- 
      native-wheel-picker-android|react-native-skeleton-placeholder|@react-native- 
      masked-view/masked-view|react-native-linear-gradient||react-native-image- 
      slider-box|react-native-vector-icons|@sentry/react-native|react-native-radio- 
      buttons-group|@notifee/react-native|react-native-push-notification||react- 
      native-image-progress|react-native-progress||react-native-swipe-list- 
      view|react-native-date-picker|@ptomasroos/react-native-multi-slider|react- 
      native-select-dropdown|react-native-base64|react-native-gifted-charts|react- 
      native-android-open-settings|react-native-signature-canvas|react-native- 
      maps|react-native-open-maps|react-native-gifted-chat|react-native-rsa- 
      native|react-native-dropdown-picker|lottie-react-native|react-native-app-intro- 
      slider|react-native-code-push|react-native-splash-screen|@react-native- 
      community/netinfo|jail-monkey|@testing-library/react-native|@testing- 
      library/jest-native)/)',
    ],
moduleNameMapper: {
  '^react-native$': '<rootDir>/__mocks__/react-native.js',
  'react-native-vector-icons/(.*)$': '<rootDir>/__mocks__/react-native-vector- 
    icons.js',
  "^@sentry/react-native$": "<rootDir>/__mocks__/@sentry/react-native.js"
 },
transform: {
   '^.+\\.[jt]sx?$': 'babel-jest',
 },
moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'json', 'node','svg'],
moduleDirectories: ['node_modules', 'src'],
};

** babel.config.js **

module.exports = {
  presets: ['module:metro-react-native-babel-preset'],
  plugins: [
    ['@babel/plugin-transform-class-properties', { loose: true }],
    ['@babel/plugin-transform-private-methods', { loose: true }],
    ['@babel/plugin-transform-private-property-in-object', { loose: true }]
   ],
 env: {
   production: {
     plugins: ['transform-remove-console'],
   },
  },
 };

** Example component **

import React from 'react';
import {Button, Text, View} from 'react-native';
import {render, fireEvent} from '@testing-library/react-native';

 function Example() {
   return (
     <View>
      <Button
       title="Print Username"
       onPress={() => {
         console.log('hi');
       }}
      />
      <Text testID="printed-username">hi</Text>
     </View>
   );
 }

 test('renders the Example component and simulates a button press', () => {
    const {getByTestId, getByText} = render(<Example />);

    const printedUsername = getByTestId('printed-username');
    expect(printedUsername.props.children).toBe('hi');

    // Simulate the button press
    const button = getByText('Print Username');
    fireEvent.press(button);
   // jest.spyOn(console, 'log').mockImplementation(() => {});
});

i have tried importing expect but still the issue been found .

import { expect } from '@jest/globals';

** Package.json **

   "@testing-library/react-native": "^12.7.2",
   "react": "18.3.1",
   "react-native": "0.71.6",
   "@babel/core": "^7.25.8",
   "@babel/plugin-transform-class-properties": "^7.25.7",
   "@babel/plugin-transform-private-methods": "^7.25.7",
   "@babel/plugin-transform-private-property-in-object": 
     "^7.25.8",
   "@babel/preset-env": "^7.20.0",
   "@babel/preset-react": "^7.25.7",
   "@babel/runtime": "^7.20.0",
   "jest": "^29.7.0",
   "react-test-renderer": "^18.3.1",

Metadata

Metadata

Assignees

No one assigned

    Labels

    questionFurther information is requested

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions