简体   繁体   English

使用 axios 执行经过身份验证的请求时,Jest 返回“网络错误”

[英]Jest returns "Network Error" when doing an authenticated request with axios

This seems a bit weird to me.这对我来说似乎有点奇怪。 I'm trying to test an actual (ie. real.network) request with Jest.我正在尝试使用 Jest 测试实际(即 real.network)请求。

These are the tested scenarios:这些是经过测试的场景:

  • Test an external API (fixer.io) with no headers <--- This works测试一个没有标题的外部 API (fixer.io) <--- 这有效
  • Test a local API server with headers <--- This does NOT work使用标头测试本地 API 服务器<--- 这不起作用
  • Test same local API with headers from node terminal <--- This works使用来自node终端的标头测试相同的本地 API <--- 这有效

What could be the reason behind this behavior?这种行为背后的原因可能是什么? And what is the 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) )

It can be a Jest configuration issue. 它可能是Jest配置问题。 I solved forcing "node" as jest environment in package.json: 我解决了强制“node”作为package.json中的jest环境:

"jest": { "testEnvironment": "node" } “jest”:{“testEnvironment”:“node”}

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

Jest allows you to set a setup script file. Jest允许您设置安装脚本文件。 This file will be required before everything else and gives you a chance to modify the environment in which the tests will run. 其他所有内容之前都需要此文件,并且您有机会修改运行测试的环境。 This way you can unset XMLHttpRequest before axios is loaded and the adapter type evaluated since imports are hoisted. 这样,您可以在加载axios之前取消设置XMLHttpRequest,并在挂起导入之后评估适配器类型。 https://facebook.github.io/jest/docs/configuration.html#setuptestframeworkscriptfile-string https://facebook.github.io/jest/docs/configuration.html#setuptestframeworkscriptfile-string

This worked for me: 这对我有用:

package.json 的package.json

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

__tests__/setup.js __tests __ / setup.js

global.XMLHttpRequest = undefined;

That is funny,that the axios used XMLHttpRequest by primary,and ajax request can't access across domain,so your test failed ,so you can let your code pass by set the axios adapter. 有趣的是,axios主要使用XMLHttpRequest,而ajax请求无法跨域访问,因此您的测试失败,因此您可以通过设置axios适配器来让代码通过。

The Reason by axios/defaults.js 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;
 }

Solution change axios adapter to http 解决方案将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);
});

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

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

then the test can be access http via ajax 然后测试可以通过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);
    });

I resolved it by adding 我通过添加来解决它

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

for a specific test case file, as setting global.XMLHttpRequest = undefined or env=node was causing my other test cases to fail. 对于特定的测试用例文件,因为设置global.XMLHttpRequest = undefined或env = node导致我的其他测试用例失败。

I work on Next.js projects where I have both frontend and backend tests and setting testEnvironment to 'node' does not work.我在 Next.js 项目上工作,在这些项目中我同时进行了前端和后端测试,并且将testEnvironment设置为“节点”不起作用。

So I configure jest.config.js as所以我将jest.config.js配置为

testEnvironment: 'jest-environment-jsdom',

and add并添加

/**
 * @jest-environment node
 */

to all backend tests.所有后端测试。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM