首页 > 解决方案 > 为什么我的 jest 测试在带有 typescript 的 React Native 中失败了?

问题描述

我已经使用 typescript 设置了一个非常非常简单的组件来响应本机。我的目标只是设置 Jest 并通过一个简单的测试。这是 App.tsx 的代码:

import React from 'react';
import { StyleSheet, Text, View } from 'react-native';

export default function App() {
  return (
    <View style={styles.container}>
      <Text>Hello World!</Text>
    </View>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: '#fff',
    alignItems: 'center',
    justifyContent: 'center',
  },
});

和测试:

import React from 'react';
import App from '../App';

import { create } from "react-test-renderer";

test('renders correctly', () => {
  const tree = create(<App />);
  expect(tree.toJSON()).toMatchSnapshot();
});

'Hello World' 按预期呈现,但是当我运行测试时,我得到:

  console.error
    Warning: React.createElement: type is invalid -- expected a string (for built-in componen
ts) or a class/function (for composite components) but got: object.

事实上,当我检查导出的函数“App 的类型”时,它是 React.Element 而不是组件。但这是为什么呢?它正在返回一个元素,但我认为这就是组件应该做的事情。导出本身是一个无状态函数,所以我有点困惑......

更新:Dennis Tsoi 添加了

"moduleFileExtensions": [
  "ts",
  "tsx",
  "js"
],

到 package.json 中的 'jest' 对象并修复了类型错误。似乎 expo 客户端并没有创建在 react native 中运行 tpyescript 所需的一切

标签: reactjstypescriptreact-nativejestjs

解决方案


编辑:

通过查看远程存储库, https://github.com/adamglang/rnTranslatedBible

该错误与 package.json 中缺少的玩笑配置有关。


笔记:


解决方案:

包.json

  "jest": {
    "preset": "react-native",
    "moduleFileExtensions": [
      "ts",
      "tsx",
      "js"
    ]
  },

根据 jest docs,默认配置是:

Default: ["js", "json", "jsx", "ts", "tsx", "node"]

通过改变顺序,将"ts""tsx"移到 前面js,问题就解决了。


建议 react-native-testing-library 因为 react-test-renderer 可能会对 react-native 产生一些问题;

注意:需要react-native-testing-library作为 devDependancy。

评论:

  • someRN 开发人员使用 react-native-testing-library 作为测试其组件的简单方法;以及允许方法基于深度嵌套的组件树快速断言值。

为什么 React-native-testing-library 解决了:

你想为你的 React Native 组件编写可维护的测试而不测试实现细节,但是你被告知使用 Enzyme,你了解到它没有 React Native 适配器,这意味着只支持浅渲染。你想渲染深度!但是深度渲染可能需要 jsdom(React Native 不是 web!),而使用 react-test-renderer 进行深度渲染非常痛苦。

例子

应用程序.tsx

import React from 'react';
import { StyleSheet, Text, View } from 'react-native';

export default function App() {
  return (
    <View style={styles.container}>
      <Text>Hello World!</Text>
    </View>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: '#fff',
    alignItems: 'center',
    justifyContent: 'center',
  },
});

测试.ts

import React from "react";
import { render } from "react-native-testing-library";
import App from "../App";

describe("App", () => {

  it("App", async () => {
    const component = render(<App />);
    expect(component.toJSON()).toMatchSnapshot();
  });
});

编辑[附加快照]

exports[`App App 1`] = `
<View
  style={
    Object {
      "alignItems": "center",
      "backgroundColor": "#fff",
      "flex": 1,
      "justifyContent": "center",
    }
  }
>
  <Text>
    Hello World!
  </Text>
</View>
`;

推荐阅读