使用酶jest react-native在componentDidMount中更新状态之后测试组件

时间:2017-07-26 09:01:05

标签: react-native state enzyme jest

我有一个反应原生的组件

export default class SearchResultsScreen extends Component {
   constructor(props){
      super(props);
      this.state = {
        centres: [],
      };
  };

   componentDidMount() {
        let searchUrl =`${hostname}centres_search/`;
        let lat = this.props.origin_lat;
        let long = this.props.origin_long;
        let distance = this.props.distance;
        let url = `${searchUrl}origin_lat=${lat}&origin_long=${long}&distance=${distance}`
        console.log('before fetch called');
        fetch(url)
          .then((response) => response.json())
          .then((responseJson) => {
             console.log('before state updated '+responseJson[0].name);
             this.setState({
              centres: responseJson,
             });
             console.log('after fetch called '+responseJson[0].name);
          })
          .catch((error)=>{
             console.log('error '+error);
             this.setState({
               centres: [],
             });
          });
   }

   static navigationOptions = {
      title: 'Centers',
      headerTitleStyle: navigationHeaderStyle
   };

   render() {
      let centresList;
      if(typeof this.state.centres == 'undefined' ||
          this.state.centres.length == 0) {
          centresList = <Text>No results found</Text>
      } else {
         centresList = <FlatList
             data={this.state.centres}
             keyExtractor={(item, index) => item._centre_id}
             renderItem={({item}) => <CentreComponent Centre={item}/>}
             ItemSeparatorComponent={() => <ListSeperator />}
          />
      }

    return(
       <View>
          {centresList}
          <ListSeperator />
       </View>
    );
   };
}

所以基本上它根据fetch的响应(即得到的结果数)加载CentreComponent。

在我使用Jest的测试中,我试图断言存在一个类型为CentreComponent的组件。我的测试看起来像这样:

jest.disableAutomock();
import 'react-native';
import React from 'react';
import {shallow, mount, render} from 'enzyme';
import SearchResultsScreen from '../../src/SearchResultsScreen/index';
import CentreComponent from 
    '../../src/SearchResultsScreen/CentreComponent';
import renderer from 'react-test-renderer';

describe('SearchResultsScreen', () => {
  test.only('renders more than one CentreComponent', () => {
    jest.useFakeTimers();
    global.fetch = jest.fn().mockImplementation(() => {
        let kc = [{
          _centre_id: 1,
          name: 'test',
          address_1: 'abc',
          address_2: 'def',
          city: 'so',
          postcode: 'tt',
        }, {
          _centre_id: 2,
          name: 'testee',
          address_1: 'abc',
          address_2: 'def',
          city: 'so',
          postcode: 'tt',
        }]
        console.log('mock fetch called');

        return new Promise((resolve, reject) => {
          process.nextTick(
            () => resolve({ok: true, json: function(){return kc}})
          );
        });
     });

     const checkbox = mount(<SearchResultsScreen origin_long='5' origin_lat='2' distance='5'/>);
     jest.runAllTicks();
     checkbox.update();
     expect(checkbox.find(KarCentreComponent)).toHaveLength(2);
   });
});

当我运行测试时       jest.js --env = jsdom

我看到按顺序打印以下console.log:

console.log('before fetch called');
console.log('mock fetch called');
console.log('before state updated '+responseJson[0].name);

Error at line:
console.log('error '+error);

我得到的错误是:

  { Invariant Violation: Element type is invalid: expected a string (for 
  built-in components) or a class/function (for composite components) 
  but got: undefined. You likely forgot to export your component from 
  the file it's defined in. Check the render method of 
  `SearchResultsScreen`

所以我怀疑是,当componentDidUpdate正在调用时

  this.setState({
          centres: responseJson,
         });

它正在抛出一个被#34; catch&#34;

捕获的异常

0 个答案:

没有答案