Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bug running Jest with ScrollView dependant components #13034

Closed
alvaromb opened this issue Mar 20, 2017 · 8 comments
Closed

Bug running Jest with ScrollView dependant components #13034

alvaromb opened this issue Mar 20, 2017 · 8 comments
Labels
Good first issue Interested in collaborating? Take a stab at fixing one of these issues. Help Wanted :octocat: Issues ideal for external contributors. JavaScript Resolution: Locked This issue was locked by the bot.

Comments

@alvaromb
Copy link
Contributor

Description

When running npm run test, the default tests index.ios.js and index.android.js fail due to the following error:

    TypeError: _this._scrollView.scrollTo is not a function

      at TabViewPagerScroll._this._scrollTo (node_modules/react-native-tab-view/src/TabViewPagerScroll.js:68:19)
      at TabViewPagerScroll.componentDidMount (node_modules/react-native-tab-view/src/TabViewPagerScroll.js:123:197)
      at node_modules/react-test-renderer/lib/ReactCompositeComponent.js:265:25
      at measureLifeCyclePerf (node_modules/react-test-renderer/lib/ReactCompositeComponent.js:75:12)
      at node_modules/react-test-renderer/lib/ReactCompositeComponent.js:264:11
      at CallbackQueue.notifyAll (node_modules/react-test-renderer/lib/CallbackQueue.js:76:22)
      at ReactTestReconcileTransaction.close (node_modules/react-test-renderer/lib/ReactTestReconcileTransaction.js:36:26)
      at ReactTestReconcileTransaction.closeAll (node_modules/react-test-renderer/lib/Transaction.js:206:25)
      at ReactTestReconcileTransaction.perform (node_modules/react-test-renderer/lib/Transaction.js:153:16)
      at batchedMountComponentIntoNode (node_modules/react-test-renderer/lib/ReactTestMount.js:69:27)

Reproduction

$ react-native init Test
$ cd Test/
$ yarn add react-navigation
$ npm run test

Solution

I'm open to send a PR with a fix if somebody can guide me through this. Could be here https://github.com/facebook/react-native/blob/dbe555ba78d7b0f79e482c62787db2fc3d897848/Libraries/Components/ScrollView/__mocks__/ScrollViewMock.js?

Additional Information

  • React Native version: 0.42.0
  • Platform: both
  • Operating System: macOS Sierra
  • Dev tools: iOS 10.2
@janicduplessis
Copy link
Contributor

janicduplessis commented Mar 20, 2017

Yea looks like the issue is that the ScrollView mock doesn't have any of the methods ScrollView has. Maybe we could use jest.genMockFromModule to create a mock of the original component class and then extend it to override the render method. This will make sure we create mock functions for every method of ScrollView.

const ScrollViewComponent = jest.genMockFromModule('ScrollView');

class ScrollViewMock extends ScrollViewComponent {
  render() {
    ...
  }
}

Not sure if that would work but if it does it would be nice to avoid having to fix the mock if we add other methods to ScrollView. If it doesn't work we could also just add empty methods for each one in ScrollView.

@janicduplessis
Copy link
Contributor

PR would be nice, let me know if you need any help.

@janicduplessis janicduplessis added Good first issue Interested in collaborating? Take a stab at fixing one of these issues. Help Wanted :octocat: Issues ideal for external contributors. labels Mar 20, 2017
alvaromb added a commit to APSL/react-native that referenced this issue Mar 21, 2017
@alvaromb
Copy link
Contributor Author

Hi @janicduplessis!

Thanks for your support, here's the PR #13048

Your suggested change worked perfectly, however when testing this specific case with the react-navigation library, the Linking library mock also fails. There's a workaround for that, so I was able to confirm the new ScrollViewMock is working. I don't know if the Linking mock issue belongs to this repo or the library, but if you feel it can be solved inside RN I can open a new issue/PR.

There's also a flow warning for using jest in the mock, please feel free to ping me if I need to perform further changes for that.

alvaromb added a commit to APSL/react-native that referenced this issue Mar 21, 2017
Added lint rule to avoid unresolved identifier error
@jurassix
Copy link

jurassix commented Apr 6, 2017

I ran into this issue and was able to mock this simply:

jest.mock('ScrollView', () => jest.genMockFromModule('ScrollView'));

Also, I'm mocking the Linking module as well from here that @alvaromb provided:

jest.mock('Linking', () => ({
  addEventListener: jest.fn(),
  removeEventListener: jest.fn(),
  openURL: jest.genMockFn().mockReturnValue(Promise.resolve()),
  canOpenURL: jest.genMockFn().mockReturnValue(Promise.resolve()),
  getInitialURL: jest.genMockFn().mockReturnValue(Promise.resolve()),
}))

Note, I've configured this to be run as part of Jests setupFiles configuration.

@erikfox
Copy link

erikfox commented Jul 11, 2017

@janicduplessis Was this completed/should be closed? Is Linking mock mentioned above still an issue?

@renatobenks-zz
Copy link

This PR it's on development? I'm with the same issue so, if I can help it, would be nicely.

@minhhai2209
Copy link

This solution

jest.mock('ScrollView', () => jest.genMockFromModule('ScrollView'));

works well but it also removes ScrollView content from snapshots, which reduces the test coverage.

Here is what I'm using:

jest.mock('ScrollView', () => {
  const RealComponent = require.requireActual('ScrollView');
  const React = require('React');
  class ScrollView extends React.Component {
    scrollTo() {
    }

    render() {
      return React.createElement('ScrollView', this.props, this.props.children);
    }
  }
  ScrollView.propTypes = RealComponent.propTypes;
  return ScrollView;
});

@sam-vdp
Copy link
Contributor

sam-vdp commented Nov 8, 2017

@minhhai2209 Great solution! One small improvement, your code broke all my existing snapshot tests, because the ScrollView mock shipped with react-native renders slightly differently. This worked for me:

jest.mock('ScrollView', () => {
  const MockScrollView = require.requireMock('ScrollViewMock');
  const React = require('React');  
  const RealScrollView = require.requireActual('ScrollView');
  class ScrollView extends React.Component {
    scrollTo() {
    }

    render() {
      return (
        <MockScrollView {...this.props} />
      );
    }
  }
  ScrollView.propTypes = RealScrollView.propTypes;
  return ScrollView;
});

bowerman0 pushed a commit to bowerman0/react-native that referenced this issue Dec 5, 2017
Summary:
Solves facebook#13034

Now the `ScrollView` mock has all the methods available.

React Native tests pass.

To test this specific part of the code,

```sh
$ react-native init Test
$ cd Test/
$ yarn add react-navigation
```

Then, add a simple project that uses `react-navigation`:

```js
import React from 'react';
import { Text } from 'react-native';
import { StackNavigator } from 'react-navigation';

class HomeScreen extends React.Component {
  static navigationOptions = {
    title: 'Welcome',
  };
  render() {
    return <Text>Hello, Navigation!</Text>;
  }
}

const SimpleApp = StackNavigator({
  Home: { screen: HomeScreen },
});

export default SimpleApp
```

Run the default render tests:

```js
$ npm run test
```
Closes facebook#13048

Differential Revision: D4746028

Pulled By: shergin

fbshipit-source-id: cb1791978d15be7f5d14b7b22979388066ad6caa
bowerman0 pushed a commit to bowerman0/react-native that referenced this issue Dec 5, 2017
Summary:
Solves facebook#13034

Now the `ScrollView` mock has all the methods available.

React Native tests pass.

To test this specific part of the code,

```sh
$ react-native init Test
$ cd Test/
$ yarn add react-navigation
```

Then, add a simple project that uses `react-navigation`:

```js
import React from 'react';
import { Text } from 'react-native';
import { StackNavigator } from 'react-navigation';

class HomeScreen extends React.Component {
  static navigationOptions = {
    title: 'Welcome',
  };
  render() {
    return <Text>Hello, Navigation!</Text>;
  }
}

const SimpleApp = StackNavigator({
  Home: { screen: HomeScreen },
});

export default SimpleApp
```

Run the default render tests:

```js
$ npm run test
```
Closes facebook#13048

Differential Revision: D4746028

Pulled By: shergin

fbshipit-source-id: cb1791978d15be7f5d14b7b22979388066ad6caa
@facebook facebook locked as resolved and limited conversation to collaborators Nov 28, 2018
@react-native-bot react-native-bot added the Resolution: Locked This issue was locked by the bot. label Nov 28, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Good first issue Interested in collaborating? Take a stab at fixing one of these issues. Help Wanted :octocat: Issues ideal for external contributors. JavaScript Resolution: Locked This issue was locked by the bot.
Projects
None yet
Development

No branches or pull requests

9 participants