我有一个反应原生的组件
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;
捕获的异常