React Native:节点

时间:2017-05-22 11:02:58

标签: react-native jestjs enzyme

组件:

import React from 'react';
import PropTypes from 'prop-types';
import { StyleSheet, ListView } from 'react-native';
import Card from './card';

const styles = StyleSheet.create( {
  container: {
    flex: 1,
  },
} );

export default class PhotoList extends React.Component {
  static propTypes = {
    feeds: PropTypes.arrayOf( PropTypes.object ),
  };

  static defaultProps = {
    feeds: [],
  };

  constructor( props ) {
    super( props );

    const ds = new ListView.DataSource( { rowHasChanged: ( r1, r2 ) => r1 !== r2 } );
    this.state = {
      dataSource: ds.cloneWithRows( this.props.feeds ),
    };
  }

  render() {
    return (
      <ListView
        enableEmptySections
        style={ styles.container }
        dataSource={ this.state.dataSource }
        renderRow={ feedItem => <Card feed={ feedItem } /> }
      />
    );
  }
}

__嘲笑__ / react.js

const react = require( 'react' );
// Resolution for requestAnimationFrame not supported in jest error :
// https://github.com/facebook/react/issues/9102#issuecomment-283873039
global.window = global;
window.addEventListener = () => {};
window.requestAnimationFrame = () => {
  throw new Error( 'requestAnimationFrame is not supported in Node' );
};

module.exports = react;

光list.test.js

import React from 'react';
import { ListView } from 'react-native';
import renderer from 'react-test-renderer';
import { shallow } from 'enzyme';
import PhotoList from './photo-list';

const feed = {
  url: 'http://placehold.it/600x600',
  title: 'Some title for the card',
};

describe( '<PhotoList />', () => {
  it( 'should render without throwing an error', () => {
    const component = renderer.create(
      <PhotoList feed={ feed } />,
    ).toJSON();
    expect( component ).toMatchSnapshot();
  } );

  it( 'should contain a ListView', () => {
    const wrapper = shallow( <PhotoList feed={ feed } /> );
    expect( wrapper.find( ListView ).length ).toBe( 1 );
  } );
} );

错误:

 FAIL  src/components/photo-list.test.js
  ● Console

    console.error node_modules/react-native/Libraries/Core/ExceptionsManager.js:71
      React caught an error thrown by ListView. You should fix this error in your code. Consider adding an error boundary to your tree to customize error handling behavior.

      Error: requestAnimationFrame is not supported in Node

      The error is located at:
          in ListView (created by PhotoList)
          in PhotoList

      The error was thrown at:
          at Object.<anonymous>.window.requestAnimationFrame (/Users/rahulshetty/localshiva/test-rn-apps/__mocks__/react.js:7:7),
          at Component.requestAnimationFrame (/Users/rahulshetty/localshiva/test-rn-apps/node_modules/react-timer-mixin/TimerMixin.js:16:14),
          at Component.componentDidMount (/Users/rahulshetty/localshiva/test-rn-apps/node_modules/react-native/Libraries/CustomComponents/ListView/ListView.js:365:6),
          at commitLifeCycles (/Users/rahulshetty/localshiva/test-rn-apps/node_modules/react-test-renderer/lib/ReactFiberCommitWork.js:421:24),
          at commitAllLifeCycles (/Users/rahulshetty/localshiva/test-rn-apps/node_modules/react-test-renderer/lib/ReactFiberScheduler.js:349:9),
          at invokeGuardedCallback (/Users/rahulshetty/localshiva/test-rn-apps/node_modules/react-test-renderer/lib/ReactErrorUtils.js:21:10),
          at invokeGuardedCallback (/Users/rahulshetty/localshiva/test-rn-apps/node_modules/react-test-renderer/lib/ReactErrorUtils.js:91:34),
          at commitAllWork (/Users/rahulshetty/localshiva/test-rn-apps/node_modules/react-test-renderer/lib/ReactFiberScheduler.js:468:19),
          at completeUnitOfWork (/Users/rahulshetty/localshiva/test-rn-apps/node_modules/react-test-renderer/lib/ReactFiberScheduler.js:614:11),
          at performUnitOfWork (/Users/rahulshetty/localshiva/test-rn-apps/node_modules/react-test-renderer/lib/ReactFiberScheduler.js:641:14)
    console.warn node_modules/react-native/Libraries/Core/ExceptionsManager.js:40
      Unable to symbolicate stack trace: this.dispatchEvent is not a function

  ● <PhotoList /> › should render without throwing an error

    requestAnimationFrame is not supported in Node

      at Object.<anonymous>.window.requestAnimationFrame (__mocks__/react.js:7:7)
      at Component.requestAnimationFrame (node_modules/react-timer-mixin/TimerMixin.js:16:14)
      at Component.componentDidMount (node_modules/react-native/Libraries/CustomComponents/ListView/ListView.js:365:6)
      at commitLifeCycles (node_modules/react-test-renderer/lib/ReactFiberCommitWork.js:421:24)
      at commitAllLifeCycles (node_modules/react-test-renderer/lib/ReactFiberScheduler.js:349:9)
      at invokeGuardedCallback (node_modules/react-test-renderer/lib/ReactErrorUtils.js:21:10)
      at invokeGuardedCallback (node_modules/react-test-renderer/lib/ReactErrorUtils.js:91:34)
      at commitAllWork (node_modules/react-test-renderer/lib/ReactFiberScheduler.js:468:19)
      at completeUnitOfWork (node_modules/react-test-renderer/lib/ReactFiberScheduler.js:614:11)
      at performUnitOfWork (node_modules/react-test-renderer/lib/ReactFiberScheduler.js:641:14)

问题:

我是测试的新手,我使用Create React Native App设置了一个React Native项目,以了解单元测试。我不确定导致此错误的原因。我希望测试我的组件中是否存在ListView。如何添加对requestAnimationFrame的支持?

1 个答案:

答案 0 :(得分:1)

你可以放:

if (!window.requestAnimationFrame) {
  let targetTime = 0
  window.requestAnimationFrame = function (callbackFun) {
    const currentTime = +new Date()
    const timeoutCb = function () { callbackFun(+new Date()) }
    return window.setTimeout(timeoutCb, Math.max(targetTime + 16, currentTime) - currentTime)
  }
}

进入您的代码以在节点中polifill requestAnimationFrame。我假设你正在使用jsdom所以你已经有了窗口。如果您不想模拟行为,可以更简单地使用Ofc代码,并且可以在测试之外将其提取出来以获得更清晰的代码。