react-native-picker / picker

Picker is a cross-platform UI component for selecting an item from a list of options.
MIT License
1.45k stars 273 forks source link

jest test setup #148

Open Runkunkun opened 3 years ago

Runkunkun commented 3 years ago

That is my testfile for a component where i use react-native-picker, when i run it i get this error. How can i setup my testfile so it does not fail?

`Invariant Violation: Native module cannot be null.

  at invariant (node_modules/invariant/invariant.js:40:15)
  at new NativeEventEmitter (node_modules/react-native/Libraries/EventEmitter/NativeEventEmitter.js:37:7)
  at Object.<anonymous> (node_modules/react-native-reanimated/lib/commonjs/ReanimatedEventEmitter.js:4:16)
  at Object.<anonymous> (node_modules/react-native-reanimated/lib/commonjs/core/AnimatedCall.js:2:1)`

import React from "react"; import { shallow } from "enzyme"; import ReceiptOverlay from "../receiptOverlay";

describe("ReceiptOverlay", () => { test("renders correctly", () => { const tree = shallow(); expect(tree.debug()).toMatchSnapshot(); }); });

srinu6 commented 3 years ago

hey @Runkunkun, how you fixed this issue? need help!

yomua commented 2 years ago

I have encountered the same problem. Have you solved it?

martsie commented 2 years ago

Here's our solution:

// __mocks__/@react-native-picker/picker.tsx

import { Picker as ActualPicker } from '@react-native-picker/picker'
import { ReactNode } from 'react'
import { Platform, View } from 'react-native'

export type PickerWithFocusMock = typeof ActualPicker & {
  focusMock: typeof jest.fn
}

export class Picker extends ActualPicker<unknown> {
  // Fix Jest errors due to 'null' being returned from picker items.
  static Item: React.ComponentType = function PickerItem(): JSX.Element {
    return <></>
  }

  static focusMock = jest.fn()

  // Due to the picker view being mapped to a regular View in tests,
  // focus and blur will error unless overriden.
  focus = Picker.focusMock
  blur = (): void => {
    /* */
  }

  render(): ReactNode {
    // Transfer testID and other props to react view for testing
    if (Platform.OS === 'android') {
      return <View {...this.props} />
    }

    return super.render()
  }
}

and then in your test you can do things like:

  const onFocus = jest.spyOn(RNPicker as PickerWithFocusMock, 'focusMock')
  expect(onFocus).toBeCalledTimes(1)