web-dev-qa-db-ja.com

Reactネイティブでtypescriptを使用すると、私のjestテストが失敗するのはなぜですか?

TypeScriptを使用して、reactネイティブで本当にシンプルなコンポーネントをセットアップしました。私の目標は、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」オブジェクトに追加すると、typerrorが修正されます。エキスポクライアントは、反応したネイティブでtpyescriptを実行するために必要なすべてを作成しないようです

5
HelloWorld

編集:

リモートリポジトリを見ると、 https://github.com/adamglang/rnTranslatedBible

このエラーは、package.jsonに欠落しているjest設定に関連しています。


注意:


解決:

package.json

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

Jest docsによると、デフォルトの設定は次のとおりです。

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

順序を変更することにより、"ts"および"tsx"jsの前に移動すると、問題は解決します。


React-test-rendererがreact nativeでいくつかの問題を抱えている可能性があるため、react-native-testing-libraryを提案してください。

:devDependancyとして react-native-testing-library が必要です。

解説:

  • 一部のRN開発者は、コンポーネントをテストする簡単な方法として、react-native-testing-libraryを使用しています。また、深くネストされたコンポーネントツリーに基づいてメソッドが値をすばやくアサートできるようにします。

React-native-testing-libraryが解決する理由:

React実装コンポーネントの詳細をテストせずにネイティブコンポーネントの保守可能なテストを記述したいが、Reactネイティブアダプター、つまり浅いレンダリングのみがサポートされています。そして、深くレンダリングしたいのですが、ディープレンダリングではjsdomが必要になる場合があります(React NativeはWebではありません!)。

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',
  },
});

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();
  });
});

[スナップショットを添付]を編集

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

ここに私が働いた解決策があります。 Appコンポーネントをレンダリングする別のreactコンポーネントを作成しました。

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

import  renderer from "react-test-renderer";

function AppMirror(){
    return (
        <App />
    )
}

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

ただし、反応コンポーネントとして認識されない主な理由はわかりません。あなたがそれを理解するならば、コメントで知らせてください、そして私は私の答えを編集することができます。

これが関連するGitHub Issue です。

0
Fatih Aktaş