typescript - Jest&supertest API 测试返回 TypeError : app. 地址不是函数

标签 typescript express jestjs supertest

我目前正在制作一个带有 typescript 、节点、 express 的 API,并使用 jest 和 supertest 进行测试。我在使用 Javascript 时没有问题,但我最近将我的项目文件从 JS 更改为 TS,包括测试文件,当我开始测试时,我在所有测试套件的 super 测试请求部分都收到以下错误,这是其中之一当我开始测试时,我的终端上的测试套件。

  TypeError: app.address is not a function

  37 |     it("should return 400 if email is invalid", async () => {
  38 |       const res = await request(server)
> 39 |         .post("/api/users/auth/register")
     |          ^
  40 |         .send({
  41 |           email: "nomail",
  42 |           password: "validpassword123",

这是我的测试文件 auth.test.ts :
import * as request from 'supertest';
import { User } from '../../../../src/models/User';
import * as mongoose from 'mongoose';
import getKeys from '../../../../src/config/keys';

describe("/api/users/auth", () => {
  let server;
  let accessToken = "Bearer accessToken";
  let email;
  let password;

  beforeAll(async () => {
    server = import('../../../../src/index')
    await mongoose.connect(getKeys().mongoURI);
  })

  afterAll(async () => {
    await server.close();
    await mongoose.disconnect();
  })

  it("should return 400 if email is invalid", async () => {
    const res = await request(server)
      .post("/api/users/auth/register")
      .send({
        email: "nomail",
        password: "validpassword123",
        name: "name"
      });

    expect(res.status).toBe(400);
    expect(res.body).toHaveProperty('errArray')
  });
}

这是我的 src/index.ts 文件,它是入口点。
import * as express from 'express';
import * as passport from 'passport';
import * as bodyParser from 'body-parser';
import * as path from 'path';
import * as session from 'express-session';
import getKeys from './config/keys';

const port = 3001 || process.env.PORT;
const server = app.listen(port, () =>
  console.log(`Server running on port ${port}`)
);


export default server;

我已经尝试将导出和导入服务器语法更改为所有 commonjs 语法,并安装和设置与此相关的所有依赖项,包括 @types/supertest、@types/jest、ts-jest,这是我的设置
jest.config.js
module.exports = {
  verbose: true,
  testURL: 'http://localhost',
  testEnvironment: "node",
  roots: [
    "<rootDir>"
  ],
  transform: {
    "^.+\\.tsx?$": "ts-jest"
  },
  testRegex: "(/__tests__/.*|(\\.|/)(test|spec))\\.(jsx?|tsx?)$",
  globals: {
    "ts-jest": {
      "tsConfigFile": "tsconfig.json"
    }
  },
  moduleFileExtensions: [
    "ts",
    "tsx",
    "js",
    "jsx",
    "json",
    "node"
  ],

}

tsconfig.json
 {
  "compilerOptions": {
    "outDir": "./dist",
    "moduleResolution": "node",
    "sourceMap": true,
    "module": "commonjs",
    "allowJs": true,
    "target": "es5",
    "noUnusedParameters": false,
    "allowUnreachableCode": true,
    "allowUnusedLabels": true,
    "types": [
      "jest",
      "node",
      "express",
      "mongoose",
      "body-parser",
      "supertest"
    ],
    "lib": [
      "es2015"
    ]
  },
  "include": [
    "./src/**/*",
    "index.ts"
  ],
  "exclude": [
    "./node_modules",
    "**/*.spec.ts",
    "**/*.test.ts"
  ]
}

package.json
    "scripts": {
    "test": "jest --watchAll --runInBand",
    "coverage": "jest --coverage",
    "start": "ts-node src/index.ts",
    "server": "./node_modules/nodemon/bin/nodemon.js",
    "client": "npm start --prefix ../client",
    "dev": "concurrently \"npm run server\" \"npm run client\""
  },
"devDependencies": {
"@types/body-parser": "^1.17.0",
"@types/express": "^4.16.0",
"@types/jest": "^23.3.12",
"@types/mongoose": "^5.3.7",
"@types/node": "^10.12.18",
"@types/supertest": "^2.0.7",
"jest": "^23.6.0",
"nodemon": "^1.18.9",
"supertest": "^3.3.0",
"ts-jest": "^23.10.5",
"ts-node": "^7.0.1",
"typescript": "^3.2.2"
}

最佳答案

原因是你的server传入supertestundefined . supertest将使用 app.address()在内部,请参阅此 line .这就是它抛出错误的原因:

TypeError: app.address is not a function



如果要导入 server动态,你应该改变:

let server;
beforeAll(async () => {
  server = import('../../../../src/index')
})

到:

let server;
beforeAll(async () => {
  const mod = await import('../../../../src/index');
  server = (mod as any).default;
});

例如。
index.ts :

import express from 'express';

const app = express();

app.post('/api/users/auth/register', (req, res) => {
  res.status(400).json({ errArray: [] });
});

const port = 3001 || process.env.PORT;
const server = app.listen(port, () => console.log(`Server running on port ${port}`));

export default server;
index.test.ts :

import request from 'supertest';

describe('/api/users/auth', () => {
  let server;
  beforeAll(async () => {
    const mod = await import('./');
    server = (mod as any).default;
  });

  afterAll((done) => {
    if (server) {
      server.close(done);
    }
  });

  it('should return 400 if email is invalid', async () => {
    const res = await request(server)
      .post('/api/users/auth/register')
      .send({
        email: 'nomail',
        password: 'validpassword123',
        name: 'name',
      });

    expect(res.status).toBe(400);
    expect(res.body).toHaveProperty('errArray');
  });
});

带有覆盖率报告的集成测试结果:

☁  jest-codelab [master] ⚡  npx jest --coverage --verbose /Users/ldu020/workspace/github.com/mrdulin/jest-codelab/src/stackoverflow/54230886/index.test.ts
 PASS  src/stackoverflow/54230886/index.test.ts (10.306s)
  /api/users/auth
    ✓ should return 400 if email is invalid (56ms)

  console.log src/stackoverflow/54230886/index.ts:437
    Server running on port 3001

----------|----------|----------|----------|----------|-------------------|
File      |  % Stmts | % Branch |  % Funcs |  % Lines | Uncovered Line #s |
----------|----------|----------|----------|----------|-------------------|
All files |      100 |       50 |      100 |      100 |                   |
 index.ts |      100 |       50 |      100 |      100 |                 9 |
----------|----------|----------|----------|----------|-------------------|
Test Suites: 1 passed, 1 total
Tests:       1 passed, 1 total
Snapshots:   0 total
Time:        11.875s

源代码:https://github.com/mrdulin/jest-codelab/tree/master/src/stackoverflow/54230886

关于typescript - Jest&supertest API 测试返回 TypeError : app. 地址不是函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54230886/

相关文章:

class - 以类型为参数的 typescript 方法

angular - NGXS @Select 与状态模型的用法

Node.js 退出 clean Express starter app.js

javascript - Res.render() 不渲染

node.js - 如何将 node.js express 服务器转换为 AWS lambda?

angular - 带有路径别名的错误自动导入

typescript 定义只能包含特定字符串的数组

javascript - 如何在两个属性上使用 Vue/Vuetify 自动完成过滤器?

javascript - 为什么 useState 不在单元测试(Jest、Enzyme)中重新渲染组件?

reactjs - Babel 配置错误 : Support for the experimental syntax 'jsx' isn't currently enabled