React Native中getByText无法匹配文本,Jest测试报错如何解决?
解决React Native Jest测试SysError组件的文本断言问题
问题场景
在React Native 0.68项目中,使用Jest结合@testing-library/react-native v11.0.0测试SysError.js组件(该组件由react-navigation 6.x路由传参),目标是验证页面是否包含指定提示文本,但测试断言始终失败。
SysError.js组件代码
import React, {useState, useContext, Component} from 'react'; import {Platform, Button, Text, TouchableOpacity, View } from 'react-native'; export default function SysError({route}) { // 由react-navigation路由传参 const message = route.params.message ? JSON.stringify(route.params.message) : ""; return ( <View styles={{marginTop: 32, paddingHorizontal: 24, alignItems:"center", alignContent:"center"}}> <Text>{route.params.message} System NOT available right now. Try again later</Text> </View> ) };
初始测试代码
import React from 'react'; import { render, cleanup } from "@testing-library/react-native"; import SysError from './SysError'; afterEach(cleanup); it ('describe SysError page view with a message', () => { const route = {params: {message:"nnmm"}}; const {toJSON, getByText} = render(<SysError route={route} />); const foundmsg = getByText("System NOT available right now"); // 此处抛出错误 expect(toJSON()).toMatchSnapshot(); expect(foundmsg.props.children).toEqual("System NOT available right now"); })
第一次测试错误
FAIL src/components/app/SysError.test.js ● describe SysError page view with a message Unable to find an element with text: System NOT available right now 9 | const route = {params: {message:"nnmm"}}; 10 | const {toJSON, getByText} = render(<SysError route={route} />); > 11 | const foundmsg = getByText("System NOT available right now"); | ^ 12 | expect(toJSON()).toMatchSnapshot(); 13 | expect(foundmsg.props.children).toEqual("System NOT available right now"); 14 | at Object.getByText (src/components/app/SysError.test.js:11:22)
修改为正则匹配后的错误
将getByText改为正则匹配后:
const foundmsg = getByText(/System NOT available right now/i);
出现新错误:
expect(received).toEqual(expected) // deep equality Expected: "System NOT available right now" Received: ["nnmm", " System NOT available right now. Try again later"] 11 | const foundmsg = getByText(/System NOT available right now/i); 12 | expect(toJSON()).toMatchSnapshot(); > 13 | expect(foundmsg.props.children).toEqual("System NOT available right now");
解决方案
核心原因
组件中<Text>元素的children是一个数组(由传入的route.params.message和固定文本拼接而成),而非单一字符串,直接断言等于目标字符串必然失败。
可行的断言修改方式
方式1:使用toHaveTextContent断言文本存在
利用@testing-library/react-native提供的匹配器,直接验证元素包含目标文本,无需操作props.children:
it ('describe SysError page view with a message', () => { const route = {params: {message:"nnmm"}}; const {toJSON, getByText} = render(<SysError route={route} />); const foundmsg = getByText(/System NOT available right now/i); expect(toJSON()).toMatchSnapshot(); expect(foundmsg).toHaveTextContent("System NOT available right now"); })
方式2:断言数组元素包含目标文本
如果一定要访问props.children,可以直接检查数组的第二个元素(固定文本部分)是否包含目标内容:
expect(foundmsg.props.children[1]).toContain("System NOT available right now");
方式3:优化组件代码(可选)
将组件中的文本拼接为单一字符串,让children成为字符串类型:
// 组件中修改Text内容 <Text>{`${route.params.message} System NOT available right now. Try again later`}</Text>
此时测试断言可以改为:
expect(foundmsg.props.children).toEqual(expect.stringContaining("System NOT available right now"));
注意:之前尝试的
toEqual(/System NOT available right now/i)无效,因为该语法是断言值为正则对象本身,而非字符串匹配正则。
内容的提问来源于stack exchange,提问作者user938363
相关产品推荐
相关产品推荐

