question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Tests failing when using BottomSheetFlatList

See original GitHub issue

Bug

Initially, I had an existing issue with reanimated. I tried using the first and second solutions but I’m still having the same issue as described in the comment: React.createElement: type is invalid – expected a string

Relevant Jest setup:

jest.mock("react-native-reanimated", () => {
  const reanimated = require("react-native-reanimated/mock");
  reanimated.default.addWhitelistedUIProps = () => {};
  reanimated.default.addWhitelistedNativeProps = () => {};

  return reanimated;
});

jest.mock("@gorhom/bottom-sheet", () => require("react-native-reanimated/mock"));

Relevant code

import { BottomSheetFlatList } from "@gorhom/bottom-sheet";

class CreateWorkoutExercisesSelectionModal extends React.Component<
  CreateWorkoutExercisesSelectionModalProps,
  ICreateWorkoutExercisesSelectionModalOwnState
> {
  public static get options() {
    return topBarSetupCreateWorkoutExerciseSelection();
  }

  public constructor(props: CreateWorkoutExercisesSelectionModalProps) {
    super(props);
    this.state = {
      searchText: "",
      showTags: false,
      exerciseTags: this.props.exerciseTags,
      ...this.getStateUpdateForFilteredExercises(this.props.exerciseDataForWorkout)
    };
    this.handleSearchByText = this.handleSearchByText.bind(this);
    this.filterByTags = this.filterByTags.bind(this);
  }

  public render(): React.ReactNode {
    const eqTags = this.state.exerciseTags.filter(tag => tag.type === WorkoutTagsType.EQUIPMENT);
    const bodyTags = this.state.exerciseTags.filter(tag => tag.type === WorkoutTagsType.BODY_PART);
    const styles = CreateWorkoutExercisesSelectionModalStyle();

    return (
      <View testID={CreateWorkoutExercisesSelectionModalTestIDs.container} style={styles.drawerRoot}>
        {this.renderSearchInput(styles)}
        {this.renderTagsForFilter(eqTags, CreateWorkoutExercisesSelectionModalTestIDs.tagsEquipment, styles)}
        {this.renderTagsForFilter(bodyTags, CreateWorkoutExercisesSelectionModalTestIDs.tagsBody, styles)}
        <View style={styles.drawerToolbar}>
          {this.renderNumberOfSearchResults(styles)}
          {this.renderToggleForFilter(styles)}
        </View>
        {this.renderExercises(styles)}
      </View>
    );
  }

  private renderExercises(styles: ICreateWorkoutExercisesSelectionModalStyle) {
    return (
      <BottomSheetFlatList
        data={this.state.filteredExerciseDataForWorkoutIDs}
        renderItem={this.renderSingleFlatListItem}
        testID={CreateWorkoutExercisesSelectionModalTestIDs.list}
        keyExtractor={this.flatListKeyExtractor}
        getItemLayout={this.getItemLayoutForFlatList}
        style={styles.exercisesList}
      />
    );
  }
}

Relevant test

it("should render list of exercises selection", () => {
    const { getByTestId } = renderWithRedux(<CreateWorkoutExercisesSelectionModal />, reduxStore);

    dispatchExerciseSelection(0);
    dispatchExerciseSelection(0);
    const expectedNumberOfAddedExercises = "2";
    expect(getByTestId("3682-right-text").props.children).toBe(expectedNumberOfAddedExercises);
  });

Environment info

Library Version
@gorhom/bottom-sheet 2.0.4
react-native 0.63.4
react-native-reanimated 1.13.2
react-native-gesture-handler 1.9.0

Steps to reproduce

Setup a project with @gorhom/bottom-sheet Use @testing-library/react-native to test a component with BottomSheet from @gorhom/bottom-sheet

Reproducible sample code

import { BottomSheetFlatList } from "@gorhom/bottom-sheet";
import { render } from "@testing-library/react-native";
import React from "react";
import { Text } from "react-native";

describe("Tests for workout creation screen, exercises selection modal", () => {
  it("should render list of exercises selection", () => {
    const { getByTestId } = render(<BottomSheetFlatList data={[1, 2, 3]} renderItem={() => <Text>hello</Text>} />);
    expect(getByTestId("3682-right-text").props.children).toBe(3);
  });
});

For this test, I get:

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.

      at createFiberFromTypeAndProps (node_modules/react-test-renderer/cjs/react-test-renderer.development.js:14410:21)
      at createFiberFromElement (node_modules/react-test-renderer/cjs/react-test-renderer.development.js:14433:15)
      at reconcileSingleElement (node_modules/react-test-renderer/cjs/react-test-renderer.development.js:4982:23)
      at mountChildFibers (node_modules/react-test-renderer/cjs/react-test-renderer.development.js:5042:35)
      at reconcileChildren (node_modules/react-test-renderer/cjs/react-test-renderer.development.js:7234:28)
      at updateContextProvider (node_modules/react-test-renderer/cjs/react-test-renderer.development.js:8680:3)
      at beginWork$1 (node_modules/react-test-renderer/cjs/react-test-renderer.development.js:9081:14)
      at performUnitOfWork (node_modules/react-test-renderer/cjs/react-test-renderer.development.js:12649:12)
      at workLoopSync (node_modules/react-test-renderer/cjs/react-test-renderer.development.js:12622:22)
      at performSyncWorkOnRoot (node_modules/react-test-renderer/cjs/react-test-renderer.development.js:12333:9)

Issue Analytics

  • State:closed
  • Created 3 years ago
  • Reactions:4
  • Comments:8

github_iconTop GitHub Comments

7reactions
enstulencommented, Jul 15, 2021

For BottomSheet and BottomSheetScrollView, this worked for me:

jest.mock('react-native-reanimated', () =>
    jest.requireActual('../node_modules/react-native-reanimated/mock'),
)

jest.mock('@gorhom/bottom-sheet', () => {
    const react = require('react-native')
    return {
        __esModule: true,
        default: react.View,
        BottomSheetScrollView: react.ScrollView,
    }
})
5reactions
mohanderecommented, Dec 19, 2021

This helped me -

Mock for react-native-reanimated library -

// __mocks__/react-native-reanimated.js
module.exports = require('react-native-reanimated/mock');

Mock for bottom sheet -

//__mocks__/@gorhom/bottom-sheet.tsx
import React from 'react';
import { View, ScrollView, Modal, FlatList } from 'react-native';

const BottomSheetModalContext = React.createContext(null);

const BottomSheetModalProvider = (props: any) => {
  return <BottomSheetModalContext.Provider {...props} value={{}} />;
};
const BottomSheet = (props: any) => <View {...props} />;
const BottomSheetModal = (props: any) => <Modal {...props} />;

const BottomSheetBackdrop = (props: any) => <View {...props} />;
const BottomSheetHandle = (props: any) => <View {...props} />;
const BottomSheetFooter = (props: any) => <View {...props} />;
const BottomSheetScrollView = (props: any) => <ScrollView {...props} />;
const BottomSheetFlatList = (props: any) => <FlatList {...props} />;

const useBottomSheet = jest.fn();
const useBottomSheetModal = jest.fn();
const useBottomSheetSpringConfigs = jest.fn();
const useBottomSheetTimingConfigs = jest.fn();
const useBottomSheetInternal = jest.fn();
const useBottomSheetDynamicSnapPoints = jest.fn();

export { useBottomSheet };
export { useBottomSheetModal };
export { useBottomSheetSpringConfigs };
export { useBottomSheetTimingConfigs };
export { useBottomSheetInternal };
export { useBottomSheetDynamicSnapPoints };

export {
  BottomSheetModalProvider,
  BottomSheetBackdrop,
  BottomSheetHandle,
  BottomSheetModal,
  BottomSheetFooter,
  BottomSheetScrollView,
  BottomSheetFlatList,
};

export default BottomSheet;

In case if you need mock for react-native-gesture-handler.js

// __mocks__/react-native-gesture-handler.js
import { View, ScrollView, FlatList, TouchableOpacity } from 'react-native';

module.exports = {
  ScrollView,
  FlatList,
  TouchableOpacity,
  PanGestureHandler: View,
  attachGestureHandler: () => {},
  createGestureHandler: () => {},
  dropGestureHandler: () => {},
  updateGestureHandler: () => {},
  Direction: {
    RIGHT: 1,
    LEFT: 2,
    UP: 4,
    DOWN: 8,
  },
  State: {
    BEGAN: 'BEGAN',
    FAILED: 'FAILED',
    ACTIVE: 'ACTIVE',
    END: 'END',
    UNDETERMINED: 'UNDETERMINED',
  },
};

Hope this helps!

Read more comments on GitHub >

github_iconTop Results From Across the Web

Unit Testing in React: Full Guide on Jest and Enzyme Testing
Discover how to start and proceed with the testing of React ... If one or another component fails, it will cause failing in...
Read more >
How can I exclude a library from a Jest unit test?
App is using TypeScript and React Navigation. Although the app is working, after adding PendoSDK, it is failing most of my Jest unit...
Read more >
How to Run and Write Tests - React Native
Keep this in mind when running tests using Xcode. If you see an unexpected failure, see if it's disabled in objc-test.sh first.
Read more >
Snapshot Testing - Jest
The test will fail if the two snapshots do not match: either the change is unexpected, or the reference ... Snapshot Testing with...
Read more >
React Unit Testing Using Enzyme and Jest - Toptal
js Component Using TDD. The first step is to create a failing test which will try to render a React.js Component using the...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found