即使在调试中,React Native 测试库也找不到文本

Posted

技术标签:

【中文标题】即使在调试中,React Native 测试库也找不到文本【英文标题】:React Native Testing Library doesn't find text even though its in debug 【发布时间】:2019-05-04 12:33:39 【问题描述】:

我正在使用 TypeScript 构建一个 React Native 应用程序。我正在使用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 测试库看不到这段文字?我该如何测试?

【问题讨论】:

【参考方案1】:

问题是使用 RTL 的 render 方法渲染组件不会与测试用例同步发生。所以当it 块运行时你不能确定这行代码

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 助手。

【讨论】:

以上是关于即使在调试中,React Native 测试库也找不到文本的主要内容,如果未能解决你的问题,请参考以下文章

无法在博览会上调试/测试我的 react-native 应用程序

未启用远程调试器时,React Native Detox 测试失败

如何在 React-Native 中禁用远程 JS 调试

使用 react native 调试器查看网络流量

在小米手机上调试react-native白屏问题

如何在带有 Jest 的 react-native 中使用模拟的 fetch() 对 API 调用进行单元测试