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を実行するために必要なすべてを作成しないようです
編集:
リモートリポジトリを見ると、 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 が必要です。
解説:
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>
`;
ここに私が働いた解決策があります。 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 です。