Mad*_*adu 1 integration-testing node.js express supertest jestjs
我对 Nodejs 很陌生,我正在 udemy 上学习 Nodejs 课程,listen EADDRINUSE: address already in use :::4000在多次重新运行集成测试时我遇到了一些麻烦。第一次成功,但后来我在以下行中收到上述错误
const server = app.listen(port, () => {winston.info(`Listening on port ${port}`)});\nRun Code Online (Sandbox Code Playgroud)\n\n我正在粘贴我的index.js和两个测试文件,如果有人能指出我,这对我来说将是一个很大的帮助。
\n\n索引.js
\n\n const Joi = require("@hapi/joi");\n Joi.objectId = require("joi-objectid")(Joi);\n const winston = require("winston");\n const express = require("express");\n const app = express();\n\n require("./startup/logging")();\n require("./startup/config")();\n require("./startup/dbconnectivity")();\n require("./startup/routes")(app);\n const port = process.env.port || 4000;\n const server = app.listen(port, () => {winston.info(`Listening on port ${port}`)});\n // exporting server object to be used in integration tests.\n module.exports = server;\n\n\n**Integration test file for Genre**\n\nconst request = require("supertest");\nlet server;\nconst {Genere} = require("../../models/genere");\nconst {User} = require("../../models/user");\n\ndescribe("/api/genere", () => {\n beforeEach(() => {\n console.log("Before each Genre");\n server = require("../../index");\n });\n afterEach(async () => {\n console.log("After each Genre");\n await Genere.deleteMany({});\n await server.close();\n });\n\n describe("/GET", () => {\n it("should return list of generes", async() => {\n await Genere.insertMany([\n {name: "genre1"},\n {name: "genre2"},\n {name: "genre3"}\n ]);\n const res = await request(server).get("/api/geners");\n expect(res.status).toBe(200);\n console.log("response body is : " + res.body);\n expect(res.body.length).toBe(3);\n expect(res.body.map(g => g.name)).toContain("genre1");\n });\n });\n\n describe("/GET/:id", () => {\n it("should return genre with id", async() => {\n const genre = new Genere({name: "genre1"});\n await genre.save();\n const res = await request(server).get("/api/geners/"+ genre.id);\n expect(res.status).toBe(200);\n expect(res.body.name).toBe("genre1");\n });\n\n it("should return error with invalid id", async() => {\n const genre = new Genere({name: "genre1"});\n await genre.save();\n const res = await request(server).get("/api/geners/1");\n expect(res.status).toBe(404);\n expect(res.text).toMatch(/Invalid/);\n\n });\n });\n\n describe("/POST", () => {\n it("should return 401 if not authorized", async() => {\n const genere = new Genere({name: "genere1"});\n const res = await request(server).post("/api/geners").send(genere);\n expect(res.status).toBe(401);\n });\n\n it("should return 400 if the name is less than 4 chars", async() => {\n const res = await createRequestWithGenre({name: "g1"});\n expect(res.status).toBe(400);\n });\n\n it("should return 400 if the name is greater than 25 chars", async() => {\n const genreName = Array(26).fill("a").join("");\n const res = await createRequestWithGenre({name: genreName})\n expect(res.status).toBe(400);\n });\n\n it("should return 201 with gener object if proper object is sent", async() => {\n const res = await createRequestWithGenre({name: "genre1"})\n expect(res.status).toBe(201);\n expect(res.body).toHaveProperty("_id");\n expect(res.body).toHaveProperty("name", "genre1");\n\n const genre = await Genere.find({ name: "genre1"});\n expect(genre).not.toBe(null);\n });\n\n async function createRequestWithGenre(genre) {\n const token = new User().generateAuthToken();\n return await request(server)\n .post("/api/geners")\n .set("x-auth-token", token)\n .send(genre);\n }\n });\n});\nRun Code Online (Sandbox Code Playgroud)\n\n一旦我添加另一个用于集成测试的文件(如下所示),我就开始收到此文件代码后面提到的错误。
\n\nconst {User} = require("../../models/user");\n const {Genere} = require("../../models/genere");\n const request = require("supertest");\nlet token;\n\n describe("middleware", () => {\n\n beforeEach(() => {\n console.log("Before each Middleware");\n token = new User().generateAuthToken();\n server = require("../../index");\n });\n\n afterEach(async () => {\n console.log("After each Middleware");\n await Genere.deleteMany({});\n await server.close();\n });\n\n const exec = async() => {\n return await request(server)\n .post("/api/geners")\n .set("x-auth-token", token)\n .send({name: "gener1"});\n }\n\n it("should return 400 if invalid JWT token is sent", async() => {\n token = "invalid_token";\n const res = await exec();\n expect(res.status).toBe(400); \n expect(res.text).toBe("Invalid auth token");\n });\n });\nRun Code Online (Sandbox Code Playgroud)\n\n控制台错误
\n\nmiddleware\n \xe2\x9c\x95 should return 400 if invalid JWT token is sent (510ms)\n\n \xe2\x97\x8f middleware \xe2\x80\xba should return 400 if invalid JWT token is sent\n\n listen EADDRINUSE: address already in use :::4000\n\n 10 | require("./startup/routes")(app);\n 11 | const port = process.env.port || 4000;\n > 12 | const server = app.listen(port, () => {winston.info(`Listening on port ${port}`)});\n | ^\n 13 | // exporting server object to be used in integration tests.\n 14 | module.exports = server;\n\n at Function.listen (node_modules/express/lib/application.js:618:24)\n at Object.<anonymous> (index.js:12:20)\n at Object.beforeEach (tests/integration/middleware.test.js:11:22)\nRun Code Online (Sandbox Code Playgroud)\n\n如果有人可以帮助我为什么它在多次运行中失败,那么这对我理解为什么我们需要每次打开和关闭服务器对象将非常有帮助。
\n如果您可以导入一个实例而不调用它,Supertest 就能够管理 Express/koaapp本身的设置/拆卸。app.listen()
这涉及到代码的结构略有不同app,因此成为一个独立于服务器的模块.listen()
// app.js module
const app = require('express')()
require("./startup/logging")()
...
module.exports = app
Run Code Online (Sandbox Code Playgroud)
然后运行服务器的入口点导入然后app设置服务器.listen()
// server.js entrypoint
const app = require('./app')
const port = process.env.port || 4000;
app.listen(port, () => {winston.info(`Listening on port ${port}`)});
Run Code Online (Sandbox Code Playgroud)
当 supertest 使用导入的 时app,它将启动自己的服务器并侦听随机未使用的端口,而不会发生冲突。
// test
const request = require('supertest')
const app = require('./app')
request(app).get('/whatever')
Run Code Online (Sandbox Code Playgroud)
超级测试“服务器”实例也可以重复用于多个测试
// reuse test
const supertest = require('supertest')
const app = require('./app')
describe('steps', () => {
const request = supertest(app)
it('should step1', async() => {
return request.get('/step1')
})
it('should step2', async() => {
return request.get('/step2')
})
})
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
4425 次 |
| 最近记录: |