web-dev-qa-db-fra.com

Jest renvoie "Erreur réseau" lors d'une requête authentifiée avec axios

Cela me semble un peu bizarre. J'essaie de tester une demande réelle (c'est-à-dire un réseau réel) avec Jest.

Ce sont les scénarios testés:

  • Testez une API externe (fixer.io) sans en-têtes <--- Cela fonctionne
  • Testez un serveur d'API local avec des en-têtes <--- Cela ne fonctionne PAS
  • Testez la même API locale avec les en-têtes du terminal node<--- Cela fonctionne

Quelle pourrait être la raison de ce comportement? Et quelle est la solution?

//This WORKS
test('testing no headers', () => {
  return axios.get('http://api.fixer.io/latest')
        .then( res => console.log(res) )
});

//This DOES NOT work
test('testing no headers', () => {
  return axios.get('http://localhost:3000/users/4/profile', 
                      {headers:{authorization:`Bearer ${mytoken}`}})
        .then( res => console.log(res) )
});

//...

//Node Terminal
//This WORKS
> axios.get('http://localhost:3000/users/4/profile', 
                   {headers:{authorization:`Bearer ${mytoken}`}})
        .then( res => console.log(res) )
22
lllllll

C'est drôle, que les axios utilisent XMLHttpRequest par primaire et que la requête ajax ne puisse pas accéder à travers le domaine, donc votre test a échoué, vous pouvez donc laisser passer votre code en définissant l'adaptateur axios.

The Reason par axios/defaults.js

 function getDefaultAdapter() {
    var adapter;
    if (typeof XMLHttpRequest !== 'undefined') {
        // For browsers use XHR adapter
        adapter = require('./adapters/xhr');
    } else if (typeof process !== 'undefined') {
        // For node use HTTP adapter
        adapter = require('./adapters/http');   
    }
    return adapter;
 }

Changer la solution de l'adaptateur Axios en http

import axios from 'axios';
//This WORKS
test('testing with headers', (done) => {
    var path=require('path');
    var lib=path.join(path.dirname(require.resolve('axios')),'lib/adapters/http');
    var http=require(lib);
    axios.get('http://192.168.1.253', {
        adapter: http,
        headers: {
            Authorization: "Basic YWRtaW46bHVveGlueGlhbjkx"
        }
    }).then((res) => {
        expect(res.status).toBe(200);
        done();
    }).catch(done.fail);
});

Solution change jest testURL dans package.json

"jest": {
   "testURL":"http://192.168.1.253"
}

alors le test peut être accessible http via ajax

import axios from 'axios';
    //This WORKS
    test('testing with headers', (done) => {
        axios.get('http://192.168.1.253', {
            headers: {
                Authorization: "Basic YWRtaW46bHVveGlueGlhbjkx"
            }
        }).then((res) => {
            expect(res.status).toBe(200);
            done();
        }).catch(done.fail);
    });
18
holi-java

Il peut s'agir d'un problème de configuration Jest. J'ai résolu de forcer "node" comme environnement plaisant dans package.json:

"jest": {"testEnvironment": "node"}

voir les documents: https://facebook.github.io/jest/docs/configuration.html#testenvironment-string

33

Jest vous permet de définir un fichier de script de configuration. Ce fichier sera requis avant tout le reste et vous donne la possibilité de modifier l'environnement dans lequel les tests s'exécuteront. De cette façon, vous pouvez désactiver XMLHttpRequest avant le chargement d'axios et l'évaluation du type d'adaptateur depuis que les importations sont hissées. https://facebook.github.io/jest/docs/configuration.html#setuptestframeworkscriptfile-string

Cela a fonctionné pour moi:

package.json

{
  ...,
  "jest": {
    ...,
    "setupTestFrameworkScriptFile": "./__tests__/setup.js",
    ...
  },
  ...
}

__ tests __/setup.js

global.XMLHttpRequest = undefined;
21
chris

Je l'ai résolu en ajoutant

axios.defaults.adapter = require('axios/lib/adapters/http');

pour un fichier de cas de test spécifique, car la définition de global.XMLHttpRequest = undefined ou env = node provoquait l'échec de mes autres cas de test.

1
Ashish Sharma