NodeJS Jest测试已通过,但出现错误:在末端连接ECONREFUSED 127.0.0.1:80

eblbsuwk  于 2022-11-29  发布在  Node.js
关注(0)|答案(8)|浏览(534)

我在后端使用节点和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...');
    }
  }
}

我读到了这个question-这就是为什么我调用方法startDB

xienkqul

xienkqul1#

所以我想出来了,解决办法很简单,但我不能解释为什么。
这个req.get('api/v1/users/')应该是/api/v1/users-您需要前置的/

8iwquhpp

8iwquhpp2#

对于前端...
如果使用axios时遇到此错误,请转到testSetup.js文件并添加以下行

axios.defaults.baseURL = "https://yourbaseurl.com/"

这对我来说很有效。所以,通常情况下,这是一个baseURL问题。

pdtvr36n

pdtvr36n3#

问题略有不同,但错误消息相同...
当我尝试连接到我自己的localhost(http://localhost:4000/graphql)时,使用node-fetch时遇到了这个错误,在尝试了所有的方法后,我最可靠的解决方案是:
在package.json中使用以下脚本:"test": "NODE_ENV=test jest --watch"如果终端显示连接错误,我只需在Jest监视下转到终端,然后按a重新运行所有测试,测试通过,没有任何问题。
¯_()_/¯
通过将测试文件夹重命名为__tests__并将我的index.js移动到src/index.js,成功率继续提高。
非常奇怪,但我太累了,不能看笑话的内部来找出原因。

pb3s4cty

pb3s4cty4#

supertest的规则和express的规则是一样的。不过OvernightJS不需要任何前导或结尾的“/”。

cdmah0mi

cdmah0mi5#

对于任何登录到此页面,但不存在尾部斜杠问题的用户:
当你的express应用需要一些时间(甚至只是一秒)来重新启动/init时,jest也可以返回ECONNREFUSED。如果你像我一样使用nodemon,你可以禁用像--ignore *.test.ts这样的测试文件的重新启动。

apeeds0o

apeeds0o6#

如果您根本没有设置服务器来捕获请求,也会发生此错误(根据您的实现代码和测试,测试可能仍然通过)。

wwtsj6pe

wwtsj6pe7#

我在React前端应用程序测试中遇到此错误。
我在Assert中使用了React testing library'sfindBy*函数:

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();
});

错误就消失了。
我也不知道为什么,但也许这能帮到

UPDATE:我错误地模拟了fetch,因此我的测试调用了真实的的API,并导致了该错误

我在setupTests文件中放入了以下行:

global.fetch = jest.fn()

它模拟全局所有测试的获取。然后,您可以在测试中模拟特定的响应:

jest.mocked(global.fetch).mockResolvedValue(...)
// OR
jest.spyOn(global, 'fetch').mockResolvedValue(...)
8yparm6h

8yparm6h8#

我没有找到这个错误的根源--它与(被接受的)前导斜杠答案无关。
然而,我的“修复”是将模拟移到套件定义中--移到beforeAllafterAll中,以便在测试之间进行清理)。
之前,我在每个测试中使用mock(global.fetch),这是套件中最后一个使用mock的测试,它会导致错误。

相关问题