web-dev-qa-db-fra.com

Pourquoi mon test de plaisanterie échoue-t-il dans React natif avec dactylographié?

J'ai mis en place un composant vraiment très simple dans React native en utilisant TypeScript. Mon objectif est simplement de mettre en place Jest et de passer un test simple. Voici le code pour 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',
  },
});

et le test:

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' s'affiche comme prévu, mais lorsque j'exécute le test, j'obtiens:

  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.

Et en effet, lorsque je vérifie le type d'application de la fonction exportée, c'est un React.Element pas un composant. Mais pourquoi cela? Il renvoie un élément, mais j'ai pensé que c'était ce qu'un composant était censé faire. L'export en lui-même est une fonction sans état donc je suis un peu confus ...

MISE À JOUR: Dennis Tsoi ajouté

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

à l'objet 'jest' dans package.json et qui a corrigé l'erreur de type. Il semble que le client expo ne crée pas tout le nécessaire pour exécuter tpyescript dans react native

5
HelloWorld

Éditer:

En regardant le référentiel distant, https://github.com/adamglang/rnTranslatedBible

L'erreur était liée à une configuration jest manquante dans le package.json.


Remarque:


Solution:

package.json

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

Selon la documentation jest, la configuration par défaut est:

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

En modifiant l’ordre, "ts" et "tsx" sont déplacés devant js, le problème est résolu.


Suggérez une bibliothèque de test native comme react-test-renderer peut avoir quelques problèmes avec react native;

Remarque : requiert react-native-testing-library en tant que devDependancy.

Commentaire:

  • les développeurs someRN utilisent la bibliothèque react-native-testing-library comme moyen simple de tester leurs composants; ainsi que permettre aux méthodes d'affirmer rapidement des valeurs basées sur un arbre de composants profondément imbriqué.

Pourquoi React-native-testing-library résout:

Vous voulez écrire des tests maintenables pour vos React Composants natifs sans tester les détails d'implémentation, mais alors on vous dit d'utiliser Enzyme, dont vous apprenez qu'il n'a pas de React Adaptateur natif, ce qui signifie que seul le rendu superficiel est pris en charge. Et vous voulez un rendu profond! Mais le rendu profond peut autrement nécessiter jsdom (React Native n'est pas le Web!), Alors que faire un rendu profond avec react-test-renderer est si pénible.

Exemple

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

Modifier [Joindre un instantané]

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

Voici la solution que j'ai mise en œuvre. J'ai créé un autre composant de réaction pour rendre le composant d'application.

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

Cependant, je ne peux pas comprendre la raison principale pour laquelle il ne le voit pas comme un composant de réaction. Si vous le comprenez, faites-le moi savoir dans les commentaires et je pourrai modifier ma réponse.

Voici un GitHub associé Problème .

0
Fatih Aktaş