我是一个反应原生的新手。我已经实现了功能和快照单元测试,但不知道如何编写功能和API级别的单元测试用例。我在用酶和玩笑。我也使用redux进行状态管理。
以下是我的几个文件。
App.js
/* eslint-disable no-unused-vars */
/* eslint-disable no-use-before-define */
/* eslint-disable class-methods-use-this */
import React, { Component } from 'react';
import { StyleSheet, View } from 'react-native';
import { createStore, applyMiddleware } from 'redux';
import { Provider } from 'react-redux';
import axios from 'axios';
import axiosMiddleware from 'redux-axios-middleware';
import * as myConstant from './src/common/constants';
import reducer from './src/reducer/reducer';
import Navigation from './src/common/navigator';
const client = axios.create({
baseURL: myConstant.API,
responseType: 'json',
timeout: 25000,
});
const store = createStore(reducer, applyMiddleware(axiosMiddleware(client)));
export default class App extends Component {
render() {
return (
<Provider store={store}>
<View style={styles.container}>
<Navigation />
</View>
</Provider>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#fff',
marginTop: 50,
},
});
home.js
/* eslint-disable import/no-extraneous-dependencies */
/* eslint-disable no-unused-vars */
import React, { Component } from 'react';
import { ActivityIndicator } from 'react-native-paper';
import {
View, Text, FlatList, TouchableOpacity,
} from 'react-native';
import { connect } from 'react-redux';
import { Ionicons } from '@expo/vector-icons';
import styles from './style';
import { listRepos } from '../../reducer/reducer';
import ErrorAlert from '../../common/errorAlertComponent/errorAlert';
class Home extends Component {
componentDidMount() {
this.props.listRepos();
}
FlatListItemSeparator = () => (
<View style={styles.flatListItemSeparator} />
)
renderItem = ({ item }) => (
<View style={styles.listRowContainer}>
<TouchableOpacity onPress={() => this.props.navigation.navigate('ThumbnailViewScreen', {
albumID: item.id,
})} style={styles.listRow}>
<View style={styles.listTextNavVIew}>
<Text style={styles.albumTitle}> {item.title} </Text>
<Ionicons name='md-arrow-dropright' style={styles.detailArrow} />
</View>
</TouchableOpacity>
</View>
);
render() {
const { error, loading, albums } = this.props;
if (error) {
return <ErrorAlert />;
}
if (loading) {
return (
<View style={{ flex: 1, paddingTop: 30 }}>
<ActivityIndicator animating={true} size='large' />
</View>
);
}
return (
<View style={styles.MainContainer} >
<FlatList
styles={styles.container}
data={albums}
renderItem={this.renderItem}
ItemSeparatorComponent={this.FlatListItemSeparator}
/>
</View>
);
}
}
const mapStateToProps = (state) => {
const storedRepositories = state.albums.map((repo) => ({ key: repo.id.toString(), ...repo }));
return {
albums: storedRepositories,
loading: state.loading,
error: state.error,
};
};
const mapDispatchToProps = {
listRepos,
};
export default connect(mapStateToProps, mapDispatchToProps)(Home);
reducer.js
export const GET_ALBUM = 'album/LOAD';
export const GET_ALBUM_SUCCESS = 'album/LOAD_SUCCESS';
export const GET_ALBUM_FAIL = 'album/LOAD_FAIL';
const initialState = {
albums: [],
loading: false,
error: null,
};
export default function reducer(state = initialState, action) {
switch (action.type) {
case GET_ALBUM:
return { ...state, loading: true };
case GET_ALBUM_SUCCESS:
return { ...state, loading: false, albums: action.payload.data };
case GET_ALBUM_FAIL:
return {
...state,
loading: false,
error: 'Error while fetching albums',
};
default:
return state;
}
}
export function listRepos() {
return {
type: GET_ALBUM,
payload: {
request: {
url: 'photos/',
},
},
};
}
export function listThumb(albumId) {
return {
type: GET_ALBUM,
payload: {
request: {
url: `photos?albumId=${albumId}`,
},
},
};
}
1。react native的模拟获取
好吧,首先要测试api,你需要使用一些函数来获取(获取函数(,但这必须被嘲笑,因为你不想在测试时发出实际的请求。
// Mocking the global.fetch included in React Native
global.fetch = jest.fn();
// Helper to mock a success response (only once)
fetch.mockResponseSuccess = (body) => {
fetch.mockImplementationOnce (
() => Promise.resolve({json: () => Promise.resolve(JSON.parse(body))})
);
};
// Helper to mock a failure response (only once)
fetch.mockResponseFailure = (error) => {
fetch.mockImplementationOnce(
() => Promise.reject(error)
);
};
2.使用模拟商店
接下来你需要使用redux商店的模拟版本,你可以使用redux-mock-store
// __mocks__/redux-mock-store.js
import configureMockStore from 'redux-mock-store';
import thunk from 'redux-thunk';
const middlewares = [ thunk ];
const mockStore = configureMockStore(middlewares);
export default mockStore;
3.测试异步操作
完成这些设置之后,现在可以测试异步操作了。在这种情况下,您正在测试以下内容:
- 一个成功的请求应该触发request&成功行动
- 失败请求应该触发请求&故障操作
it('should handle TEST_API_SUCCESS action', async () => { const response = '{"items": [{"id": 1}]}'; fetch.mockResponseSuccess(response); await store.dispatch(fetchData('/test', receiveTestData)); expect(store.getActions()).toMatchSnapshot(); });
您可以在Callstack 上找到的所有信用和更多信息