为什么我的玩笑测试在带有打字稿的 React Native 中失败?

Hel*_*rld 6 typescript reactjs jestjs react-native

我已经使用 typescript 在 react native 中设置了一个非常非常简单的组件。我的目标只是设置 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',
  },
});
Run Code Online (Sandbox Code Playgroud)

和测试:

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();
});
Run Code Online (Sandbox Code Playgroud)

“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.
Run Code Online (Sandbox Code Playgroud)

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

更新:丹尼斯蔡补充道

"moduleFileExtensions": [
  "ts",
  "tsx",
  "js"
],
Run Code Online (Sandbox Code Playgroud)

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

Den*_*soi 7

Edit:

From looking at the remote repository, https://github.com/adamglang/rnTranslatedBible

The error was related a missing jest configuration in the package.json.


Note:


Solution:

package.json

  "jest": {
    "preset": "react-native",
    "moduleFileExtensions": [
      "ts",
      "tsx",
      "js"
    ]
  },
Run Code Online (Sandbox Code Playgroud)

According to the jest docs, the default configuration is:

Default: ["js", "json", "jsx", "ts", "tsx", "node"]
Run Code Online (Sandbox Code Playgroud)

By altering the order, whereby "ts" and "tsx" are moved infront of js, the issue is resolved.


Suggest react-native-testing-library as react-test-renderer can have some issues with react native;

Note: requires react-native-testing-library as a devDependancy.

Commentary:

  • someRN developer use react-native-testing-library as a simple way to test their components; as well as allowing methods to quickly assert values based on a deeply nested component tree.

Why React-native-testing-library resolves:

You want to write maintainable tests for your React Native components without testing implementation details, but then you're told to use Enzyme, which you learn has no React Native adapter, meaning only shallow rendering is supported. And you want to render deep! But deep rendering may otherwise require jsdom (React Native isn't the web!), while doing deep rendering with react-test-renderer is so painful.

Example

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',
  },
});
Run Code Online (Sandbox Code Playgroud)

test.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();
  });
});
Run Code Online (Sandbox Code Playgroud)

Edit [Attach snapshot]

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