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

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions