Я создаю приложение React Native с помощью TypeScript.Для своей навигации я использую React Navigation, а для юнит-тестирования я использую Jest и Enzyme.
Вот (урезанный) код для одного из моих экранов (LoadingScreen.tsx):
import styles from "./styles";
import React, { Component } from "react";
import { Text, View } from "react-native";
import { NavigationScreenProps } from "react-navigation";
// Is this correct?
export class LoadingScreen extends Component<NavigationScreenProps> {
// Or should I've done:
// export interface Props {
// navigation: NavigationScreenProp<any, any>;
// }
// export class LoadingScreen extends Component<Props> {
componentDidMount = () => {
this.props.navigation.navigate("LoginScreen");
};
render() {
return (
<View style={styles.container}>
<Text>This is the LoadingScreen.</Text>
</View>
);
}
}
export default LoadingScreen;
При попытке проверить экраны я столкнулся с проблемой.На экранах ожидается поддержка с типом NavigiationScreenProps, потому что я получаю доступ к React Navigations navigation
prop.Вот код тестового файла (LoadingScreen.test.tsx):
import { LoadingScreen } from "./LoadingScreen";
import { shallow, ShallowWrapper } from "enzyme";
import React from "react";
import { View } from "react-native";
import * as navigation from "react-navigation";
const createTestProps = (props: Object) => ({
...props
});
describe("LoadingScreen", () => {
describe("rendering", () => {
let wrapper: ShallowWrapper;
let props: Object;
beforeEach(() => {
props = createTestProps({});
wrapper = shallow(<LoadingScreen {...props} />);
});
it("should render a <View />", () => {
expect(wrapper.find(View)).toHaveLength(1);
});
});
});
Проблема в том, что LoadingScreen
ожидает navigation
проп.
Я получаю ошибку:
[ts]
Type '{ constructor: Function; toString(): string; toLocaleString(): string; valueOf(): Object; hasOwnProperty(v: string | number | symbol): boolean; isPrototypeOf(v: Object): boolean; propertyIsEnumerable(v: string | ... 1 more ... | symbol): boolean; }' is not assignable to type 'Readonly<NavigationScreenProps<NavigationParams, any>>'.
Property 'navigation' is missing in type '{ constructor: Function; toString(): string; toLocaleString(): string; valueOf(): Object; hasOwnProperty(v: string | number | symbol): boolean; isPrototypeOf(v: Object): boolean; propertyIsEnumerable(v: string | ... 1 more ... | symbol): boolean; }'.
(alias) class LoadingScreen
Как я могу это исправить?
Я думаю, что я каким-то образом должен насмехаться над navigation
опорой.Я попытался сделать это (как вы можете видеть, я импортировал *
из React Navigation в моем тесте), но не смог понять.Существует только NavigationActions
, который может быть полезен удаленно, но включает только navigate()
.TypeScript ожидает, что все, даже состояние, будет подделано.Как я могу издеваться над navigation
опорой?
Редактировать 1: Является ли подход использования NavigationScreenProps
даже правильным или я должен использовать подход interface Props
?Если да, то как бы вы тогда посмеялись (это приводит к той же ошибке).
Редактировать 2: Использование второго подхода с интерфейсом и
export class LoadingScreen extends Component<Props, object>
Iудалось «решить» эту проблему.Мне буквально пришлось издеваться над каждым отдельным свойством объекта навигации, как это:
const createTestProps = (props: Object) => ({
navigation: {
state: { params: {} },
dispatch: jest.fn(),
goBack: jest.fn(),
dismiss: jest.fn(),
navigate: jest.fn(),
openDrawer: jest.fn(),
closeDrawer: jest.fn(),
toggleDrawer: jest.fn(),
getParam: jest.fn(),
setParams: jest.fn(),
addListener: jest.fn(),
push: jest.fn(),
replace: jest.fn(),
pop: jest.fn(),
popToTop: jest.fn(),
isFocused: jest.fn()
},
...props
});
Остается вопрос: это правильно?Или есть лучшее решение?
Редактировать 3: Когда я использовал JS, достаточно было смоделировать только то свойство, которое мне было нужно (часто просто перемещаться).Но с тех пор, как я начал использовать TypeScript, мне пришлось высмеивать все аспекты навигации.В противном случае TypeScript будет жаловаться, что компонент ожидает пропеллер с другим типом.