我正在尝试为控制器编写单元测试,它是用 react-native 和 expo 编写的 以下是单元测试失败的登录方法
登录.tsx
import React, { useState } from 'react';
import { StyleSheet, SafeAreaView, Text, Button, Image, View, Alert, TouchableWithoutFeedback, TouchableOpacity, NativeSyntheticEvent, TextInputChangeEventData, TextInput } from 'react-native';
import axios from "axios"
import { StackNavigationProp } from '@react-navigation/stack';
import { RouteProp } from '@react-navigation/native';
import { RootStackParamList } from '~/navigations/Navigations'
interface props {
navigation: StackNavigationProp<RootStackParamList, 'Login'>;
route: RouteProp<RootStackParamList, 'Login'>;
value: string;
name: string;
}
const instance = axios.create({
baseURL: '',
timeout: 3000,
timeoutErrorMessage: 'do again',
});
const Login: React.FC<props> = ({ value, name, ...props }) => {
const [inputValue, setInputValue] = useState({
email: "",
pwd: ""
});
const [errorMesseage, setErrorMesseage] = useState("");
const onChangeText = (e: string, name: string): void => {
let input = e;
setInputValue(prev => ({
...prev,
[name]: input,
}));
if (name === "email") {
const emailRegx = /^[0-9a-zA-Z]([-_.]?[0-9a-zA-Z])*@[0-9a-zA-Z]([-_.]?[0-9a-zA-Z])*.[a-zA-Z]{3}$/i;
const emailList = ["naver.com", "gmail.com", "daum.net", "nante.com", "hanmail.net"];
let eMailAddress = input.slice(input.indexOf('@') + 1, input.length);
let eMailboolean = emailList.includes(eMailAddress) && name === 'email';
setErrorMesseage(eMailboolean && emailRegx.test(input) ? "" : "eamil regx");
}
}
const loginButton = async () => {
if (errorMesseage.length === 0) {
props.navigation.navigate("Main");
try {
const emailPost = await instance.post("/user", {
"email": inputValue.email,
"password": inputValue.pwd
});
console.log(emailPost);
} catch (error) {
if (error.response) {
console.log(error.response.data);
console.log(error.response.status);
console.log(error.response.headers);
} else if (error.request) {
console.log(error.request);
} else {
console.log('Error', error.message);
}
console.log(error.config);
}
} else {
Alert.alert("email regx");
}
}
return (
<>
<SafeAreaView style={styles.container} >
<View>
<View>
<TextInput onChangeText={text => onChangeText(text, 'email')} placeholder="email" placeholderTextColor={"#eee"} value={inputValue["email"]} autoCorrect={false} secureTextEntry={false} autoCapitalize="none" />
</View>
<Text>{errorMesseage}</Text>
<View>
<TextInput onChangeText={e => onChangeText(e, 'pwd')} placeholder="pwd" placeholderTextColor={"#eee"} value={inputValue["pwd"]} autoCorrect={false} secureTextEntry={true} autoCapitalize="none" />
</View>
<TouchableOpacity style={[styles.loginButton, { opacity: (!errorMesseage) && inputValue.pwd ? 1 : 0.3 }]} disabled={(!errorMesseage) && inputValue.pwd ? false : true} onPress={loginButton} >
<Text style={styles.loginText}>login</Text>
</TouchableOpacity>
<TouchableWithoutFeedback
onPress={() => props.navigation.navigate("Find")}
>
<Text>pwd find</Text>
</TouchableWithoutFeedback>
</View>
</SafeAreaView >
</>
);
};
export default Login;
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#fff',
alignItems: 'center',
justifyContent: 'center',
},
loginButton: {
backgroundColor: "#0095F6",
},
loginText: {
textAlign: "center",
color: "#fff"
}
});
上面代码的单元测试是用 react-native 和 expo 编写的
登录.test.tsx
import { TextInput, SafeAreaView, TouchableOpacity, TouchableWithoutFeedback, View, Text } from 'react-native';
import React from 'react';
import { render, cleanup, fireEvent } from 'react-native-testing-library';
import '@testing-library/jest-dom/extend-expect'
import TestRenderer from 'react-test-renderer';
import Login from "../src/screen/login/Index";
afterEach(cleanup);
const createTestProps = (props: Object) => ({
navigation: {
navigate: jest.fn()
},
...props
});
describe("Login page rendering test", () => {
jest.useFakeTimers()
let props: any;
let rerender: any;
let testRenderer: any;
let testInstance: any;
beforeEach(() => {
rerender = render(<Login {...props} />);
testRenderer = TestRenderer.create(<Login {...props} />);
testInstance = testRenderer.root;
});
test('renders Login component', () => {
const component = rerender.toJSON();
expect(component).toBeTruthy();
});
it("SafeAreaView renders", () => {
expect(testInstance.findAllByType(SafeAreaView).length).toBe(1);
});
it("View renders", () => {
expect(testInstance.findAllByType(View).length).toBe(5);
});
it("textInput renders", () => {
const expectedPlaceholder = ['email', 'pwd'];
expect(testInstance.findAllByType(TextInput).length).toBe(2);
expectedPlaceholder.forEach((text: string) => {
rerender.findByPlaceholder(text);
});
});
it("TouchableOpacity renders", () => {
const element = testInstance.findByType(TouchableOpacity).findByType(Text);
expect(testInstance.findAllByType(TouchableOpacity).length).toBe(1);
expect(element.props.children).toEqual('login');
});
it("TouchableWithoutFeedback renders", () => {
const element = testInstance.findByType(TouchableWithoutFeedback).findByType(Text);
expect(testInstance.findAllByType(TouchableWithoutFeedback).length).toBe(1);
expect(element.props.children).toEqual('pwd find');
});
});
describe('login page funtion test', () => {
let props: any;
let rerender: any;
beforeEach(() => {
props = {
onChangeText: jest.fn(),
}
rerender = render(<Login {...props} />);
emailInput = rerender.getByPlaceholder('email');
fireEvent.changeText(emailInput, 'ab');
});
it('email input change', async () => {
rerender.getByDisplayValue("ab");
expect(props.onChangeText).toHaveBeenCalledWith('ab');
expect(props.onChangeText).toHaveBeenCalledTimes(1);
})
})
错误部分
describe('login page funtion test', () => {
let props: any;
let rerender: any;
beforeEach(() => {
props = {
onChangeText: jest.fn(),
}
rerender = render(<Login {...props} />);
emailInput = rerender.getByPlaceholder('email');
fireEvent.changeText(emailInput, 'ab');
});
it('email input change', async () => {
rerender.getByDisplayValue("ab");
expect(props.onChangeText).toHaveBeenCalledWith('ab');
expect(props.onChangeText).toHaveBeenCalledTimes(1);
})
})
我收到以下错误。需要知道我在这里缺少什么吗?
expect(jest.fn()).toHaveBeenCalledWith(...expected)
Expected: "ab"
Number of calls: 0
116 |
> 117 | expect(props.onChangeText).toHaveBeenCalledWith('ab');
| ^
118 | expect(props.onChangeText).toHaveBeenCalledTimes(1);
119 |
120 | })
图书馆
"expo": "^37.0.12",
"jest-dom": "^4.0.0",
"react": "~16.9.0",
"react-native": "https://github.com/expo/react-native/archive/sdk-37.0.1.tar.gz",
"react-test-renderer": "^16.13.1",
"react-native-testing-library": "^2.1.0",