React Native Testing Library не находит текст, хотя находится в режиме отладки
Я создаю приложение React Native с помощью TypeScript. Я использую React Native Testing Library для своих тестов компонентов.
У меня есть простой компонент, который отображает два кликабельных значка и текст. Это счетчик, который может увеличивать и уменьшать число.
import React, { PureComponent } from "react";
import { Text, TouchableOpacity, View } from "react-native";
import { Button, Icon } from "react-native-elements";
import { getIconName } from "../../services/core";
import styles from "./styles";
export interface AmountButtonProps {
amount: number;
onDecrement: () => void;
onIncrement: () => void;
size: "small" | "large";
}
export class AmountButtons extends PureComponent<AmountButtonProps> {
render() {
const { amount, onDecrement, onIncrement, size } = this.props;
const fontSize = size === "small" ? 14 : 26;
const minusDisabled = amount <= 1;
const plusDisabled = amount >= 25;
return (
<View style={styles.container}>
<Icon
containerStyle={[
styles[size],
styles.iconContainer,
styles.minusIcon,
minusDisabled && styles.disabled
]}
onPress={onDecrement}
type="ionicon"
name={getIconName("remove")}
disabled={minusDisabled}
disabledStyle={[styles.iconDisabled, styles.disabled]}
size={fontSize}
component={TouchableOpacity}
/>
<View style={[styles[size], styles.amountContainer, styles.iconContainer]}>
<Text style={{ fontSize }}>{amount}</Text>
</View>
<Icon
containerStyle={[
styles[size],
styles.iconContainer,
styles.addIcon,
plusDisabled && styles.disabled
]}
onPress={onIncrement}
type="ionicon"
name={getIconName("add")}
disabled={plusDisabled}
disabledStyle={styles.iconDisabled}
color="white"
size={fontSize}
component={TouchableOpacity}
/>
</View>
);
}
}
export default AmountButtons;
Я хотел написать простой модульный тест, чтобы увидеть, может ли пользователь увидеть сумму. Вот что я написал.
import React from "react";
import { debug, fireEvent, render } from "react-native-testing-library";
import { getIconName } from "../../services/core";
import AmountButtons, { AmountButtonProps } from "./AmountButtons";
const createTestProps = (props?: object): AmountButtonProps => ({
amount: 1,
onDecrement: jest.fn(),
onIncrement: jest.fn(),
size: "large",
...props
});
describe("AmountButtons", () => {
const props = createTestProps();
const { getByText, getByProps } = render(<AmountButtons {...props} />);
it("displays the amount", () => {
debug(<AmountButtons {...props} />);
expect(getByText(props.amount.toString())).toBeDefined();
});
});
Проблема в том, что этот тест выдает ошибку:
● AmountButtons › displays the amount
Component not found.
18 | it("displays the amount", () => {
19 | debug(<AmountButtons {...props} />);
> 20 | expect(getByText(props.amount.toString())).toBeDefined();
| ^
21 | });
22 |
23 | it("calls onIncrement", () => {
at Object.it (app/components/AmountButtons/AmountButtons.test.tsx:20:12)
Хотя в выводе debug
Я могу видеть сумму, оказываемую:
...
}
>
<Text
style={
Object {
"fontSize": 26,
}
}
>
1
</Text>
</View>
<Themed.Icon
...
Что здесь происходит? Почему React Testing Library не видит этот текст? Как я могу проверить это?
2 ответа
Проблема в том, что рендеринг вашего компонента с помощью RTL
render
метод не происходит синхронно с тестовым примером. Поэтому, когда блок запускается, вы не можете быть уверены, что эта строка кода
const { getByText, getByProps } = render(<AmountButtons {...props} />);
бежал и
getByText
переплетается должным образом.
Чтобы решить эту проблему, вы можете:
- переместить рендеринг внутрь
it
блокировать:
describe("AmountButtons", () => {
const props = createTestProps();
it("displays the amount", () => {
const { getByText, getByProps } = render(<AmountButtons {...props} />);
expect(getByText(props.amount.toString())).toBeDefined();
});
});
- переместить рендеринг внутри
beforeEach
/before
блокировать:
describe("AmountButtons", () => {
const props = createTestProps();
let getByText, getByProps;
beforeEach(() => {
({ getByText, getByProps }) = render(<AmountButtons {...props} />);
})
it("displays the amount", () => {
expect(getByText(props.amount.toString())).toBeDefined();
});
});
но в этом случае вы должны оставаться в
let
переменные все
getBy
помощники.
Другой способ получить текст через Query
const {queryByA11yLabel} = render(<AmountButtons />)expect(queryByA11yLabel("1")).toBeDefined()