4
votes

Comment imprimer la demande et la réponse lorsqu'un test échoue dans Jest?

J'utilise Supertest et Jest pour tester une API Node.js.

Un exemple de test a le format suivant

expect(received).toBe(expected) // Object.is equality

    Expected: 200
    Received: 404

Actuellement, lorsque l'attente échoue, le suivant est journalisé

it('Read a note for a user', (done) => {
      request(graphqlURL)
        .post('/graphql')
        .set(baseHeaders())
        .send({
          query: graphQLQuery
        })
        .end((err, res) => {
          expect(res.status).toBe(200);          
          done();
        })

    });

Je voudrais également enregistrer la requête et la réponse à côté des tests qui ont échoué pour avoir plus de contexte lors du débogage.

Y a-t-il un moyen de les imprimer également, uniquement pour les tests qui échouent?


0 commentaires

4 Réponses :


0
votes

Vous pouvez imprimer la réponse comme ceci:

it('Read a note for a user', (done) => {
  request(graphqlURL)
    .post('/graphql')
    .set(baseHeaders())
    .send({
      query: graphQLQuery
    })
    .end((err, res) => {
      if(!expect(res.status).toBe(200)) console.log('res',res) // print response
      expect(res.status).toBe(200);          
      done();
    })

  });


4 commentaires

Je voudrais imprimer la réponse uniquement si l'attente échoue. Dans ce cas, les réponses seraient imprimées indépendamment du fait que le test réussisse ou échoue


vous pouvez vérifier maintenant


Cela n'imprimera toujours pas la réponse si l'attente échoue. Il ne s'imprimera que si err est une valeur de vérité


Je cherchais une approche plus générique qui a été suggérée dans une autre réponse. Merci pour l'aide :)



3
votes

expect fonctionne en lançant une Error lorsqu'une attente échoue.

La propriété message de la Error code Erreur , ajoutez vos données supplémentaires à la propriété message , puis relancez le Error comme ceci:

it('Read a note for a user', (done) => {
  request(graphqlURL)
    .post('/graphql')
    .set(baseHeaders())
    .send({
      query: graphQLQuery
    })
    .end((err, res) => {
      try {
        expect(res.status).toBe(200);
      } catch (err) {
        // --- add additional data to the error message here ---
        err.message = `${err.message}\n\nfailing query: ${graphQLQuery}`;
        throw err;  // throw the error so test fails as expected
      }
      done();
    })
});


3 commentaires

Cela résout mon problème dans une large mesure. Il y a cependant un petit hoquet. Les instructions console.log sont imprimées séparément du rapport de test. Le rapport sur lequel les tests ont échoué est imprimé séparément des instructions console.log correspondantes pour ce test. Cela rend fastidieux de faire correspondre les demandes-réponses aux tests échoués correspondants. Des pensées sur la façon d'atténuer cela?


@dsinecos J'ai mis à jour ma réponse pour ajouter les données supplémentaires à la propriété message de la Error afin qu'elle soit imprimée dans le rapport de test


Merci beaucoup @ brian-lives-outside, cela a résolu mon problème



1
votes

Vous pouvez créer un matcher personnalisé qui enregistre la réponse en cas d'attente échoue:

it('Read a note for a user', (done) => {
  request(graphqlURL)
    .post('/graphql')
    .set(baseHeaders())
    .send({
      query: graphQLQuery
    })
    .end((err, res) => {
      expect.statusCode(200, res)     
      done()
    })
})

Ensuite, dans votre test, utilisez le matcher personnalisé au lieu du expect typique :

expect.extend({
  statusCode(expected, response) {
    const { status } = response
    const pass = expected === status

    if (pass) {
      return {
        message: () =>
          `expected ${status} to be ${expected}`,
        pass: true
      }
    } else {
      return {
        message: () =>
          `expected ${status} to be ${expected}. Response: ${response}`,
        pass: false
      }
    }
  }
})

Malheureusement, il n'y a pas vraiment de moyen d'accéder à la requête HTTP en utilisant supertest . Mais vous pouvez ajouter toute information arbitraire sur la demande que vous avez à la signature de votre correspondance personnalisée.


3 commentaires

Merci, c'est l'une des approches que j'ai envisagées. L'inconvénient que je peux voir est que je vais devoir écrire des matchers personnalisés pour différents types de comparaison. Vous avez partagé une correspondance pour le code d'état. Dans les tests, je comparerais également différentes parties du corps de la réponse. Si je comprends bien, je devrais écrire un matcher personnalisé pour chacun? Est-ce que ça a du sens?


Vous pouvez écrire un matcher personnalisé similaire avec une journalisation qui compare la réponse supertest à un autre objet et vérifie que l'objet est un sous-ensemble de la réponse. Donc quelque chose de similaire à expect.toMatchObject , mais avec le message modifié.


J'ai accepté une autre réponse. Ma préoccupation est que cela limiterait le nombre de correspondants que je peux utiliser sur ma réponse ou que je finirais par réécrire les correspondants fournis par Jest. Merci pour l'aide :)



0
votes

Si vous ajoutez des attentes supplémentaires pour le corps, il sera enregistré s'il ne correspond pas à celui attendu. Avoir cette attente avant le code d'état attendu entraînera l'effet souhaité par vous.


0 commentaires