10

TypeScript を使用して React Native アプリケーションを構築しています。コンポーネント テストにReact Native Testing Libraryを使用しています。

2 つのクリック可能なアイコンとテキストをレンダリングする単純なコンポーネントがあります。数値を増減できるカウンターです。

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 にこのテキストが表示されないのはなぜですか? どうすればこれをテストできますか?

4

1 に答える 1

1

問題は、RTL のメソッドを使用したコンポーネントのレンダリングrenderがテスト ケースと同期しないことです。したがって、itブロックが実行されると、このコード行が

const { getByText, getByProps } = render(<AmountButtons {...props} />);

実行され、getByText適切にバインドされています。

これを解決するには、次のことができます。

  1. itブロック内でレンダリングを移動:
describe("AmountButtons", () => {
  const props = createTestProps();

  it("displays the amount", () => {
    const { getByText, getByProps } = render(<AmountButtons {...props} />);
    expect(getByText(props.amount.toString())).toBeDefined();
  });
});
  1. 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

于 2021-10-17T17:33:25.557 に答える