Jest test passed but get Error: connect ECONNREFUSED 127.0.0.1:80 at the end
Jest test passed but get Error: connect ECONNREFUSED 127.0.0.1:80 at the end
我在后端使用带有 TypeScript 的节点,在后端使用 Jest 和 Supertest 作为我的测试框架。
当我尝试测试时,结果通过了,但最后出现错误。结果如下:
PASS test/controllers/user.controller.test.ts
Get all users
✓ should return status code 200 (25ms)
console.log node_modules/@overnightjs/logger/lib/Logger.js:173
[2019-12-05T04:54:26.811Z]: Setting up database ...
Test Suites: 1 passed, 1 total
Tests: 1 passed, 1 total
Snapshots: 0 total
Time: 3.284s
Ran all test suites.
server/test/controllers/user.controller.test.ts:32
throw err;
^
Error: connect ECONNREFUSED 127.0.0.1:80
at TCPConnectWrap.afterConnect [as oncomplete] (net.js:1104:14)
npm ERR! Test failed. See above for more details.
这是我的测试代码:
import request from "supertest";
import { AppServer } from '../../config/server';
const server = new AppServer();
describe('Get all users', () => {
it('should return status code 200', async () => {
server.startDB();
const appInstance = server.appInstance;
const req = request(appInstance);
req.get('api/v1/users/')
.expect(200)
.end((err, res) => {
if (err) throw err;
})
})
})
这是我的服务器设置。我在后端使用 overnightjs
。
我创建了一个 getter 来获取 Express 实例。这是来自 overnight.js.
// this should be the very top, should be called before the controllers
require('dotenv').config();
import 'reflect-metadata';
import { Server } from '@overnightjs/core';
import { Logger } from '@overnightjs/logger';
import { createConnection } from 'typeorm';
import helmet from 'helmet';
import * as bodyParser from 'body-parser';
import * as controllers from '../src/controllers/controller_imports';
export class AppServer extends Server {
constructor() {
super(process.env.NODE_ENV === 'development');
this.app.use(helmet());
this.app.use(bodyParser.json());
this.app.use(bodyParser.urlencoded({ extended: true }));
this.setupControllers();
}
get appInstance(): any {
return this.app;
}
private setupControllers(): void {
const controllerInstances = [];
// eslint-disable-next-line
for (const name of Object.keys(controllers)) {
const Controller = (controllers as any)[name];
if (typeof Controller === 'function') {
controllerInstances.push(new Controller());
}
}
/* You can add option router as second argument */
super.addControllers(controllerInstances);
}
private startServer(portNum?: number): void {
const port = portNum || 8000;
this.app.listen(port, () => {
Logger.Info(`Server Running on port: ${port}`);
});
}
/**
* start Database first then the server
*/
public async startDB(): Promise<any> {
Logger.Info('Setting up database ...');
try {
await createConnection();
this.startServer();
Logger.Info('Database connected');
} catch (error) {
Logger.Warn(error);
return Promise.reject('Server Failed, Restart again...');
}
}
}
我读了这个 - 这就是我调用方法 startDB
的原因。
所以我想通了,解决方案很简单。虽然我无法解释为什么。
这个 req.get('api/v1/users/')
应该是 /api/v1/users
- 你需要一个前导 /
.
超测规则与快递规则相同。不过,OvernightJS 不需要任何前导或结尾的“/”。
对于前端...
如果您在使用 axios
时遇到此错误,请转到 testSetup.js
文件并添加此行
axios.defaults.baseURL = "https://yourbaseurl.com/"
这对我有用。因此,通常这是一个 baseURL 问题。
问题略有不同,但错误消息相同...
我在尝试连接到我自己的本地主机 (http://localhost:4000/graphql
) 时使用 node-fetch 时遇到此错误,在尝试了一切感觉之后,我最可靠的解决方案是:
在 package.json 中使用此脚本:"test": "NODE_ENV=test jest --watch"
如果终端显示连接错误,我就去终端看 Jest,然后按 a
重新运行所有测试,它们顺利通过。
¯\_(ツ)_/¯
通过将测试文件夹重命名为 __tests__
并将我的 index.js
移动到 src/index.js
,成功率继续提高。
很奇怪,但我太累了,无法查看 Jest 内部结构以找出原因。
对于任何登陆这里,但尾部斜杠没有问题的人:
jest
也可以 return 一个 ECONNREFUSED
当你的 express 应用需要一些时间(甚至只是一秒钟)到 restart/init 时。如果您像我一样使用 nodemon
,您可以禁用 --ignore *.test.ts
.
等测试文件的重启
如果您根本没有设置服务器来捕获请求,也会出现此错误(取决于您的实现代码和测试,测试可能仍会通过)。
我在 React 前端应用程序测试中遇到了这个错误。
我在断言中使用了 React testing library's findBy*
函数:
expect(await screen.findByText('first')).toBeInTheDocument();
expect(await screen.findByText('second')).toBeInTheDocument();
expect(await screen.findByText('third')).toBeInTheDocument();
我改成后:
await waitFor(async () => {
expect(await screen.findByText('first')).toBeInTheDocument();
expect(await screen.findByText('second')).toBeInTheDocument();
expect(await screen.findByText('third')).toBeInTheDocument();
});
错误消失了。
我不知道为什么,但也许它会对某人有所帮助
更新:我错误地模拟了 fetch
,所以我的测试调用了真实的 API 并导致了那个错误
我将这一行放在我的 setupTests
文件中:
global.fetch = jest.fn()
它模拟了全局所有测试的提取。然后,您可以在测试中模拟特定的响应:
jest.mocked(global.fetch).mockResolvedValue(...)
// OR
jest.spyOn(global, 'fetch').mockResolvedValue(...)
我在后端使用带有 TypeScript 的节点,在后端使用 Jest 和 Supertest 作为我的测试框架。
当我尝试测试时,结果通过了,但最后出现错误。结果如下:
PASS test/controllers/user.controller.test.ts
Get all users
✓ should return status code 200 (25ms)
console.log node_modules/@overnightjs/logger/lib/Logger.js:173
[2019-12-05T04:54:26.811Z]: Setting up database ...
Test Suites: 1 passed, 1 total
Tests: 1 passed, 1 total
Snapshots: 0 total
Time: 3.284s
Ran all test suites.
server/test/controllers/user.controller.test.ts:32
throw err;
^
Error: connect ECONNREFUSED 127.0.0.1:80
at TCPConnectWrap.afterConnect [as oncomplete] (net.js:1104:14)
npm ERR! Test failed. See above for more details.
这是我的测试代码:
import request from "supertest";
import { AppServer } from '../../config/server';
const server = new AppServer();
describe('Get all users', () => {
it('should return status code 200', async () => {
server.startDB();
const appInstance = server.appInstance;
const req = request(appInstance);
req.get('api/v1/users/')
.expect(200)
.end((err, res) => {
if (err) throw err;
})
})
})
这是我的服务器设置。我在后端使用 overnightjs
。
我创建了一个 getter 来获取 Express 实例。这是来自 overnight.js.
// this should be the very top, should be called before the controllers
require('dotenv').config();
import 'reflect-metadata';
import { Server } from '@overnightjs/core';
import { Logger } from '@overnightjs/logger';
import { createConnection } from 'typeorm';
import helmet from 'helmet';
import * as bodyParser from 'body-parser';
import * as controllers from '../src/controllers/controller_imports';
export class AppServer extends Server {
constructor() {
super(process.env.NODE_ENV === 'development');
this.app.use(helmet());
this.app.use(bodyParser.json());
this.app.use(bodyParser.urlencoded({ extended: true }));
this.setupControllers();
}
get appInstance(): any {
return this.app;
}
private setupControllers(): void {
const controllerInstances = [];
// eslint-disable-next-line
for (const name of Object.keys(controllers)) {
const Controller = (controllers as any)[name];
if (typeof Controller === 'function') {
controllerInstances.push(new Controller());
}
}
/* You can add option router as second argument */
super.addControllers(controllerInstances);
}
private startServer(portNum?: number): void {
const port = portNum || 8000;
this.app.listen(port, () => {
Logger.Info(`Server Running on port: ${port}`);
});
}
/**
* start Database first then the server
*/
public async startDB(): Promise<any> {
Logger.Info('Setting up database ...');
try {
await createConnection();
this.startServer();
Logger.Info('Database connected');
} catch (error) {
Logger.Warn(error);
return Promise.reject('Server Failed, Restart again...');
}
}
}
我读了这个 startDB
的原因。
所以我想通了,解决方案很简单。虽然我无法解释为什么。
这个 req.get('api/v1/users/')
应该是 /api/v1/users
- 你需要一个前导 /
.
超测规则与快递规则相同。不过,OvernightJS 不需要任何前导或结尾的“/”。
对于前端...
如果您在使用 axios
时遇到此错误,请转到 testSetup.js
文件并添加此行
axios.defaults.baseURL = "https://yourbaseurl.com/"
这对我有用。因此,通常这是一个 baseURL 问题。
问题略有不同,但错误消息相同...
我在尝试连接到我自己的本地主机 (http://localhost:4000/graphql
) 时使用 node-fetch 时遇到此错误,在尝试了一切感觉之后,我最可靠的解决方案是:
在 package.json 中使用此脚本:"test": "NODE_ENV=test jest --watch"
如果终端显示连接错误,我就去终端看 Jest,然后按 a
重新运行所有测试,它们顺利通过。
¯\_(ツ)_/¯
通过将测试文件夹重命名为 __tests__
并将我的 index.js
移动到 src/index.js
,成功率继续提高。
很奇怪,但我太累了,无法查看 Jest 内部结构以找出原因。
对于任何登陆这里,但尾部斜杠没有问题的人:
jest
也可以 return 一个 ECONNREFUSED
当你的 express 应用需要一些时间(甚至只是一秒钟)到 restart/init 时。如果您像我一样使用 nodemon
,您可以禁用 --ignore *.test.ts
.
如果您根本没有设置服务器来捕获请求,也会出现此错误(取决于您的实现代码和测试,测试可能仍会通过)。
我在 React 前端应用程序测试中遇到了这个错误。
我在断言中使用了 React testing library's findBy*
函数:
expect(await screen.findByText('first')).toBeInTheDocument();
expect(await screen.findByText('second')).toBeInTheDocument();
expect(await screen.findByText('third')).toBeInTheDocument();
我改成后:
await waitFor(async () => {
expect(await screen.findByText('first')).toBeInTheDocument();
expect(await screen.findByText('second')).toBeInTheDocument();
expect(await screen.findByText('third')).toBeInTheDocument();
});
错误消失了。
我不知道为什么,但也许它会对某人有所帮助
更新:我错误地模拟了 fetch
,所以我的测试调用了真实的 API 并导致了那个错误
我将这一行放在我的 setupTests
文件中:
global.fetch = jest.fn()
它模拟了全局所有测试的提取。然后,您可以在测试中模拟特定的响应:
jest.mocked(global.fetch).mockResolvedValue(...)
// OR
jest.spyOn(global, 'fetch').mockResolvedValue(...)