在使用axios进行经过身份验证的请求时,Jest返回"网络错误"

lll*_*lll 23 javascript testing ecmascript-6 jestjs axios

这对我来说似乎有点奇怪.我正在尝试使用Jest测试实际(即真实网络)请求.

这些是经过测试的场景:

  • 测试没有标题的外部API(fixer.io) <---这是有效的
  • 使用标题测试本地API服务器 <---这不起作用
  • 使用来自node终端的 标头测试相同的本地API <---这是有效的

这种行为背后的原因是什么?什么是解决方案?

//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) )
Run Code Online (Sandbox Code Playgroud)

Dan*_*ore 33

它可能是Jest配置问题.我解决了强制"node"作为package.json中的jest环境:

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

请参阅docs:https://facebook.github.io/jest/docs/configuration.html#testenvironment-string

  • 这帮助我提出了获取请求。但是我仍然收到 post 请求的错误。有什么线索吗? (2认同)

chr*_*ris 21

Jest允许您设置安装脚本文件.其他所有内容之前都需要此文件,并且您有机会修改运行测试的环境.这样,您可以在加载axios之前取消设置XMLHttpRequest,并在挂起导入之后评估适配器类型.https://facebook.github.io/jest/docs/configuration.html#setuptestframeworkscriptfile-string

这对我有用:

的package.json

{
  ...,
  "jest": {
    ...,
    "setupTestFrameworkScriptFile": "./__tests__/setup.js",
    ...
  },
  ...
}
Run Code Online (Sandbox Code Playgroud)

__tests __/setup.js

global.XMLHttpRequest = undefined;
Run Code Online (Sandbox Code Playgroud)


hol*_*ava 20

有趣的是,axios主要使用XMLHttpRequest,而ajax请求无法跨域访问,因此您的测试失败,因此您可以通过设置axios适配器来让代码通过.

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;
 }
Run Code Online (Sandbox Code Playgroud)

解决方案将axios适配器更改为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);
});
Run Code Online (Sandbox Code Playgroud)

解决方案在package.json中更改jest testURL

"jest": {
   "testURL":"http://192.168.1.253"
}
Run Code Online (Sandbox Code Playgroud)

然后测试可以通过ajax访问http

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);
    });
Run Code Online (Sandbox Code Playgroud)

  • 问题是ajax访问跨域,因为jest中jsdom的默认url是`about:blank`,我尝试更改`document.url`但没有成功,只有通过`testURL`选项可以更改ajax的`origin` url . (2认同)

小智 15

我通过添加解决了它

axios.defaults.adapter = require('axios/lib/adapters/http');
Run Code Online (Sandbox Code Playgroud)

对于特定的测试用例文件,因为设置 global.XMLHttpRequest = undefined 或 env=node 导致我的其他测试用例失败。