SteffeyDev / react-native-popover-view

A well-tested, adaptable, lightweight <Popover> component for react-native
MIT License
613 stars 92 forks source link

Popover is not testable in react-native-testing-library #159

Open myou11 opened 1 year ago

myou11 commented 1 year ago

Describe the bug I am trying to write a test where I press a button that then shows a Popover. I receive this error when pressing the button to show the popover:

TypeError: _reactNative.NativeModules.UIManager.measure is not a function

It seems like I might need to mock the NativeModules.UIManager, so I referenced this post to do so.

jest.mock("react-native", () => {
  const RN = jest.requireActual("react-native");
  RN.UIManager.getViewManagerConfig = (name) => {
    return {};
  };
  Object.defineProperty(RN, "findNodeHandle", {
    get: jest.fn(() => () => 1),
    set: jest.fn(),
  });

  RN.NativeModules.UIManager = {
    //   measure: jest.fn(),
    measure: (node, callback) => {
      callback(undefined, undefined, 0, 0, 0, 0);
    },
  };

  return RN;
});

This then leads to this error:

node_modules/react-native-popover-view/dist/Utility.js:138
      reject(new Error('getRectForRef - current is not set'));

At this point, I'm not sure how to fix the mock to allow the test to succeed. Can someone who has successfully tested this popover with react-native-testing-library please offer me some advice on how to correctly test this Popover please?

Device/Setup Info:

ginnymin commented 1 year ago

@myou11 I checked out this issue and if you're trying to test the basic popover functionality, I was able to test that. Something like, render component, test that popover content doesn't exist, click button, test popover content does exist. I didn't have to mock anything, it looks like. I'm still on react-native-popover-view v5.1.2 and react-native v0.69.3 though, not sure if that matters.

ETA: I did wrap my component in <SafeAreaProvider></SafeAreaProvider> from react-native-safe-area-context, not sure if that helped or not either. It's been awhile since I've worked on this project so my memory is rusty. I do vaguely remember running into the same error you did though.

myou11 commented 1 year ago

Thanks for trying it out @ginnymin! I must have something wrong with my local config so I'll have to try again when I get some time. It's good to know you can query for the contents of your modal in your test though, so I know it's possible!

tysoc1222 commented 1 year ago

Currently I'm running into this same problem

tysoc1222 commented 1 year ago

@myou11 , I used an example where you were trying to mock the UIManager and got it to run successfully (note, I am using TypeScript)

jest.mock('react-native', () => {
  const RN = jest.requireActual('react-native');
  RN.UIManager.getViewManagerConfig = (name: string) => {
    return {};
  };
  Object.defineProperty(RN, 'findNodeHandle', {
    get: jest.fn(() => () => 1),
    set: jest.fn(),
  });

  RN.NativeModules.UIManager = {
    //   measure: jest.fn(),
    measure: (node: number, callback: MeasureOnSuccessCallback) => {
      callback(0, 0, 0, 0, 0, 0);
    },
  };

  return RN;
});
dieppe commented 1 year ago

After mocking the UIManager (thanks to @myou11 & @tysoc1222) I still ran into the ref.current being null problem.

Adding jest.useFakeTimers(); before the render and jest.clearAllTimers(); at the end of my test solved it for me.

Hope this helps :)

silvapereiraeduardo commented 11 months ago

I have exactly the same problem. unfortunately it didn't work to mock measure as @tysoc1222 suggested. Any other ideas on how to solve this problem?