IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

React Discussion :

Reactjs données vides lorsque je mock axios.get avec jestjs pour tester mon composant


Sujet :

React

  1. #1
    Membre averti
    Homme Profil pro
    Étudiant
    Inscrit en
    Juin 2022
    Messages
    21
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 24
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2022
    Messages : 21
    Par défaut Reactjs données vides lorsque je mock axios.get avec jestjs pour tester mon composant
    Bonjour tout le monde,

    Je développe une application en React et pour la première fois j'ai décidé de mettre en place des tests. J'ai commencé par les composants les plus simples, avec lesquels j'ai tout de même eu des problèmes, mais maintenant je voudrais tester des composants plus complexes, notamment avec des appels d'API via Axios.

    Mon application ressemble à ceci:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    import * as React from "react";
    import Axios from "axios";
    import { AnyData } from "../../interface/AnyDataInterface";
     
    interface IProps {
    }
     
    interface IState {
      loading: boolean | undefined,
      myData: AnyData | undefined
    }
     
    export default class Home extends React.Component <IProps, IState> {
      constructor (props: IProps){
        super(props);
        this.state = {
          loading: true,
          myData: {
            field: undefined,
            ...
          }
        };
      }
     
      fetchData = ():void => {
        this.setState({ loading: true });
        Axios.get<AnyData>('my-url')
          .then(res => {
            if (res.status === 200 && res != null) {
              this.setState({ myData:{... res.data} });
              this.setState({ loading: false });
            } else {
              console.log('problem when fetching the logs from backend');
                    }
            })
          .catch(error => {
            console.log(error);
          });
      }
     
      render():JSX.Element {
        return(
          <div className="container">
            <div>
                <button role="button" onClick={this.fetchData}>Search</button>
            </div>
            {this.state.loading == true ? <p>Wait</p>:
              <div role="composite">
                { Some child component that will render data }
              </div>
            }
          </div>
        );
      }
    }
    Mon test ressemble à ceci:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    import axios from 'axios';
    import React from 'react';
    import { render, screen, fireEvent, waitFor } from '@testing-library/react';
     
    import Home from './Home';
     
    jest.mock('axios');
     
    describe('Home component', () => {
     test('it can be clicked', async () => {
        const fakeData = [{
          some_field: some_data,
          ...
        }];
     
        axios.get = jest.fn().mockResolvedValue(() => 
          Promise.resolve({data: fakeData}));
     
        render(<Home />);
     
        fireEvent.click(screen.getByRole('button'));
        await waitFor(() => {
          expect(axios.get).toBeCalledWith("my-url");
        });
     
        await waitFor(() => {
          //Les deux expect devraient passer, si le titre est là, les données devraient également apparaître.
          expect(screen.getByText('some title text')).toBeInTheDocument(); //Passe sans erreur
          expect(screen.getByText('the data from fakeData that should be there')).toBeInTheDocument(); //M'envoie une erreur parce que jest est incapable de trouver some_data
        });
     });
    });
    Lorsque j'ai écrit ce test, il a échoué à chaque fois, mais le problème ne venait pas de mon test, mais de ma fonction de récupération des données. Dans le .then, j'avais une condition qui était la suivante : if (res.status === 200 && res != null) { et le res.status === 200 était une condition jamais satisfaite.

    J'ai donc supprimé cette condition et l'appel se déroule normalement. Mais j'ai dû changer une partie de mon code qui n'est normalement pas problématique, y a-t-il un moyen de simuler le statut de la réponse aussi ? Pour que je puisse remettre cette condition dans ma fonction.

    J'ai un autre problème qui apparaît maintenant, dans mon test mon composant affiche bien les informations "après le clique" mais chaque champ qui apparaît a ses données correspondantes vides, les données semblent ne pas passer bien alors que le .then passe et ne m'envoie pas dans le .catch.

    Ce qui me semble étrange, c'est qu'en supprimant la condition res.status === 200 dans ma fonction de récupération des données et en laissant la condition res != null, le test passe toujours (avec le même problème de données vides). Enfin, en ajoutant un console.log("data : ", res); dans mon .then dans ma fonction de récupération de données de mon composant j'obtiens, lorsque le test est exécuté, le log suivant : data : [Fonction (anonyme)].

    Je ne sais pas si cela peut expliquer ce comportement mais mon test est en javascript alors que mes classes et fonctions sont en Typescript. Mais les données que je remplis dans mon test ont la bonne forme (la même que le type demandé dans ma classe) donc Typescript devrait voir que le type correspond et n'avoir aucun problème particulier

    Si quelqu'un sait comment répondre à l'une ou l'autre de ces questions, cela m'aiderait vraiment, je galère sur ce test depuis un moment et cela commence à me rendre fou.

    Je viens de réaliser que dans fetchData() de mon composant, j'essaie d'accéder à res.data mais la fakeData que j'envoie dans mon test est sous la forme fakeData = [{...}]. Cela pourrait-il être la raison pour laquelle mon objet est vide ?

    J'ai essayé de changer ces fausses données dans mon test en : fakeData = [{ data : { ...}}] mais j'ai toujours le même problème de réponse vide lorsque j'appelle la méthode get de Axios.

    J'ai essayé de changer le fichier de test en un fichier .tsx et j'ai changé ma "fakeData" dans mon test en :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    jest.mock('axios');
     
    describe('Home component', () => {
     test('it can be clicked', async () => {
        const fakeData: AnyData = {
          "some_field": some_data,
          ...
        };
     
        const fakeConfig: AxiosRequestConfig<any> = {
          "maxBodyLength": -1
        };
     
        const fakeHeaders: AxiosResponseHeaders= {
          "access-control-allow-credentials": "true",
          "access-control-allow-headers": "*",
          "access-control-allow-methods": "*",
          "access-control-allow-origin": "some-url",
          "access-control-expose-headers": "scrollId",=
          "content-type": "application/json; charset=utf-8",
          ....
          "x-powered-by": "Express"
        }
     
        const res: AxiosResponse<AnyData, any> = { 
          config: fakeConfig,
          data: fakeData,
          headers: fakeHeaders,
          status: 200,
          statusText: "OK",
         };
     
        axios.get = jest.fn().mockResolvedValue(() => 
          Promise.resolve({res: res}));
     
        render(<Home />);
     
        fireEvent.click(screen.getByRole('button'));
        await waitFor(() => {
          expect(axios.get).toBeCalledWith("my-url");
        });
     
        ...
     });
    });
    Mais même avec cette méthode, ça ne fonctionne toujours pas, pourtant j'ai vraiment l'impression que le problème vient du formatage des données que j'envoie et je ne vois pas en quoi mes données diffèrent de celles demandées dans fetchData(). Quant aux champs de mes données, je suis sûr qu'ils sont bons, donc je suppose que le problème vient de la lecture de res.data dans mon composant.

    Lorsque je fais le nouveau test en mettant un console.log de myData dans fetchData() j'obtiens les données suivantes : { some_field : undefined, ... }

    Merci d'avance si vous prenez le temps de m'aider.

  2. #2
    Membre averti
    Homme Profil pro
    Étudiant
    Inscrit en
    Juin 2022
    Messages
    21
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 24
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2022
    Messages : 21
    Par défaut Réponse au problème
    J'ai finalement trouvé mon erreur, c'était au moment de réécrire la méthode axios.get.
    Le code qui marche:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
     
    jest.mock('axios');
     
    describe('Home component', () => {
     test('it can be clicked', async () => {
        const fakeData: AnyData = {
          "some_field": some_data,
          ...
        };
     
        const fakeConfig: AxiosRequestConfig<any> = {
          "maxBodyLength": -1
        };
     
        const fakeHeaders: AxiosResponseHeaders= {
          "access-control-allow-credentials": "true",
          "access-control-allow-headers": "*",
          "access-control-allow-methods": "*",
          "access-control-allow-origin": "some-url",
          "access-control-expose-headers": "scrollId",=
          "content-type": "application/json; charset=utf-8",
          ....
          "x-powered-by": "Express"
        }
     
        const res: AxiosResponse<AnyData, any> = { 
          config: fakeConfig,
          data: fakeData,
          headers: fakeHeaders,
          status: 200,
          statusText: "OK",
         };
     
        (axios.get as jest.Mock).mockResolvedValue(res); //LA LIGNE QUI A TOUT CHANGE
     
        render(<Home />);
     
        fireEvent.click(screen.getByRole('button'));
        await waitFor(() => {
          expect(axios.get).toBeCalledWith("my-url");
        });
     
        ...
     });
    });

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 2
    Dernier message: 08/04/2021, 18h28
  2. Ne pas afficher d'espace vide lorsqu'on masque un <div>
    Par guybrush007 dans le forum Général JavaScript
    Réponses: 2
    Dernier message: 03/08/2006, 11h02
  3. [SQL Server 2005] Valeur des données vides
    Par davasm dans le forum MS SQL Server
    Réponses: 2
    Dernier message: 22/06/2006, 09h38
  4. Filtrer sur les données vides dans un formulaire
    Par jevany dans le forum Access
    Réponses: 7
    Dernier message: 29/05/2006, 08h50
  5. [VB6]TextBox liés aux données vides
    Par jacma dans le forum VB 6 et antérieur
    Réponses: 5
    Dernier message: 09/12/2005, 16h39

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo