react-native-pager-view icon indicating copy to clipboard operation
react-native-pager-view copied to clipboard

Add example test to readme

Open brunocrpontes opened this issue 4 years ago • 18 comments

Summary

Testing screens with ViewPager that uses setPage function fails with the following error:

TypeError: Cannot read property 'Commands' of undefined

Tests like below will fail:

import React from 'react';
import {render, act} from '@testing-library/react-native';
import ViewPager from '@react-native-community/viewpager';
import {View} from 'react-native';

describe('ViewPager', () => {
  test('view pager should move to next view', () => {
    const viewPagerRef = React.createRef();

    const {UNSAFE_getByType} = render(
      <ViewPager ref={viewPagerRef}>
        <View testID="page1" />
        <View testID="page2" />
      </ViewPager>,
    );

    expect(UNSAFE_getByType(ViewPager)._fiber.index).toBe(0);

    act(() => {
      viewPagerRef.current.setPage && viewPagerRef.current.setPage(1);
    });

    expect(UNSAFE_getByType(ViewPager)._fiber.index).toBe(1);
  });
});

Environment info

react-native info output:

 System:
    OS: macOS 10.15.6
    CPU: (4) x64 Intel(R) Core(TM) i5-5257U CPU @ 2.70GHz
    Memory: 21.24 MB / 8.00 GB
    Shell: 5.7.1 - /bin/zsh
  Binaries:
    Node: 12.18.3 - /var/folders/vl/7sf6krl17mz491vg6rqrlkr00000gn/T/yarn--1598293332713-0.5982209185240344/node
    Yarn: 1.22.4 - /var/folders/vl/7sf6krl17mz491vg6rqrlkr00000gn/T/yarn--1598293332713-0.5982209185240344/yarn
    npm: 6.14.6 - ~/.asdf/installs/nodejs/12.18.3/bin/npm
    Watchman: 4.9.0 - /usr/local/bin/watchman
  Managers:
    CocoaPods: 1.9.3 - /usr/local/bin/pod
  SDKs:
    iOS SDK:
      Platforms: iOS 13.6, DriverKit 19.0, macOS 10.15, tvOS 13.4, watchOS 6.2
    Android SDK:
      API Levels: 28
      Build Tools: 28.0.3, 30.0.1
      System Images: android-28 | Intel x86 Atom
      Android NDK: Not Found
  IDEs:
    Android Studio: 4.0 AI-193.6911.18.40.6626763
    Xcode: 11.6/11E708 - /usr/bin/xcodebuild
  Languages:
    Java: 1.8.0_261 - /usr/bin/javac
    Python: 2.7.16 - /Users/brunocrpontes/.asdf/shims/python
  npmPackages:
    @react-native-community/cli: Not Found
    react: 16.11.0 => 16.11.0 
    react-native: 0.62.2 => 0.62.2 
  npmGlobalPackages:
    *react-native*: Not Found

Library version: 4.1.6

Steps to reproduce

  1. Create a test with <ViewPager />
  2. Take its ref like <ViewPager ref={ref => viewPager = ref}
  3. Call viewPager.setPage(/* page value */)

Describe what you expected to happen:

  1. Call setPage doesn't throw any errors.
  2. Update value of index in component reference.

brunocrpontes avatar Aug 24 '20 18:08 brunocrpontes

Hey, Thank you for reporting an issue. What platform is affected ?

From my POV, you should call it using current like below: https://github.com/react-native-community/react-native-viewpager/blob/master/example/ViewPagerExample.js#L103

troZee avatar Aug 25 '20 07:08 troZee

I'm having the same issue, but only when running in test environment on Android platform. The test fails with the same error message the OP is having. I'm not using the library directly, but through a third party (react-native-scrollable-tab-view), and they are using an Animated version with: Animated.createAnimatedComponent(ViewPager)

Covicake avatar Aug 25 '20 12:08 Covicake

Hey, Thank you for reporting an issue. What platform is affected ?

From my POV, you should call it using current like below: https://github.com/react-native-community/react-native-viewpager/blob/master/example/ViewPagerExample.js#L103

It's happening in testing platform, in my Jest tests to be more exactly. Run it on device works fine.

I'm mocking package to workaround the issue, like below:


jest.mock('@react-native-community/viewpager', () => {
  const RealComponent = jest.requireActual('@react-native-community/viewpager');
  const React = require('react');

  return class ViewPager extends RealComponent {
    index = 0;

    setPage = (page) => {
      this.index = Math.max(
        0,
        Math.min(page, React.Children.count(this.props.children)),
      );
    };
  };
});

Update: I added a test example that fails in issue description.

brunocrpontes avatar Aug 25 '20 17:08 brunocrpontes

@brunocrpontes Thank you for providing an example. I don't understand, what would you like to achieve in your test ?

troZee avatar Aug 28 '20 11:08 troZee

My test example isn't the best, is just to achieve error mentioned in issue.

In my case I built an paginated form using view pager as base component, part of my test is move to next page and try to capture some dependent instances of it, but in tests I can't move to next page. So current workaround is mocking it like my previous comment.

brunocrpontes avatar Aug 28 '20 11:08 brunocrpontes

You cannot use below code

  const RealComponent = jest.requireActual('@react-native-community/viewpager');

because viewpager has native implementation. There is no javascript logic inside.

If you would like to test VP, you need to mock this class and then mock implantation for onPageSelected method.

troZee avatar Aug 28 '20 12:08 troZee

@troZee understood, but why onPageSelected? I wish to move to next view pager page, the error came from "Commands" in setPage implementation.

brunocrpontes avatar Aug 28 '20 12:08 brunocrpontes

VP changes pages using onPageSelected , so why you want you use setPage method ? You can check in tests, if setPage has been called, once eg button clicked

troZee avatar Aug 28 '20 12:08 troZee

Hmm, I will try that and back with a feedback. Thanks @troZee for help!

brunocrpontes avatar Aug 28 '20 12:08 brunocrpontes

Any updates on this? Still not sure how to test it

EduVencovsky avatar Jun 29 '21 20:06 EduVencovsky

likewise, i have the same error as well

finalight avatar Aug 10 '21 06:08 finalight

Any updates on this? Still not sure how to test it

likewise, i have the same error as well

What is an issue with mocking this component ?

troZee avatar Aug 10 '21 09:08 troZee

Any updates on this? Still not sure how to test it

likewise, i have the same error as well

What is an issue with mocking this component ?

for some reason, the link that you gave is not valid anymore

do you have the updated link for that?

finalight avatar Aug 10 '21 09:08 finalight

when using the above example, you get: TypeError: Super expression must either be null or a function So i'm also unsure how to mock. I have to use setPage because I have an external button clicking through my onboarding

JaccoGoris avatar Aug 31 '21 15:08 JaccoGoris

Any news? how to test?

DuduKova avatar Nov 02 '21 14:11 DuduKova

Hey Guys! I think it's not the best approach but i managed to solve it with this mock:

jest.mock('react-native-pager-view', () => {
  const RealComponent = jest.requireActual('react-native-pager-view')
  const React = require('react')

  return class ViewPager extends React.Component {
    index = 0

    setPage = page => {
      this.index = Math.max(
        0,
        Math.min(page, React.Children.count(this.props.children))
      )
    }

    render() {
      return <RealComponent.default />
    }
  }

diegotsi avatar Nov 16 '21 13:11 diegotsi

In my case I needed to test rendered content in the TabView (witch uses the PagerView). With this mock I was able to get it to work:

jest.mock("react-native-pager-view", () => {
  const RealComponent = jest.requireActual("react-native-pager-view");
  const React = require("react");

  return class PagerView extends React.Component {
    index = 0;

    setPage = (page) => {
      this.index = Math.max(
        0,
        Math.min(page, React.Children.count(this.props.children))
      );
    };

    render() {
      return (
        <RealComponent.default>{this.props.children}</RealComponent.default>
      );
    }
  };
});

steffenabel avatar Feb 03 '22 17:02 steffenabel

Took me so long to get to the bottom of this - if anyone needs to test the tab change event and the onIndexChange function, you can add this mock file or use jest.mock as others have suggested:

// __mocks__/react-native-pager-view.js

import React from 'react';
import { View } from 'react-native';

/**
 * This mock exists because there's no official jest setup for this library yet.
 *
 * @see {@link https://github.com/callstack/react-native-pager-view/issues/220}
 * @see {@link https://github.com/callstack/react-native-pager-view/issues/481}
 */
class PagerView extends React.Component {
  setPage(selectedPage: number) {
    this.props.onPageSelected?.({ nativeEvent: { position: selectedPage } });
  }

  render() {
    const { children, style, scrollEnabled, accessibilityLabel } = this.props;

    return (
      <View testID={this.props.testID} style={style} scrollEnabled={scrollEnabled} accessibilityLabel={accessibilityLabel}>
        {children}
      </View>
    );
  }
}

export { PagerView };

export default PagerView;

nujhong avatar Jun 23 '22 07:06 nujhong

People sent several examples to test that component, so i'm closing this issue.

brunocrpontes avatar Jun 21 '23 01:06 brunocrpontes