node.js - 在 jest 拆解中杀死一个 Node.js 服务器(在 jest 的安装钩子(Hook)中启动)

标签 node.js child-process

我正在使用Jest作为测试库并在其 setup hook 内(在我所有的测试之前执行),我 spawn在某个端口上启动测试服务器的子进程。 安装代码基本上执行一个 NPM 命令:

"run-server-test": "NODE_ENV=test SERVER_PORT=3001 node src/index.js &",
"test": "NODE_ENV=test SERVER_PORT=3001 jest --detectOpenHandles --forceExit",

这是设置函数:

const { spawn } = require("child_process")

module.exports = async function setup() {
  return new Promise((resolve, reject) => {
    const testServerProcess = spawn("npm", ["run", "run-server-test"])

    testServerProcess.on("error", err => {
      console.log("Failed to start subprocess.", err)
      reject(err)
    })

    testServerProcess.stdout.on("data", data => {
      if (data.toString().startsWith("Apollo Server")) {
        console.log(`\nTest server running with PID ${testServerProcess.pid}`)
        resolve(true)
      }
    })

    testServerProcess.stderr.on("data", data => {
      console.error(`stderr: ${data}`)
      reject(new Error(data.toString()))
    })
  })
}

请注意,我使用 & 在后台执行该命令。当 Jest 完成其工作时,我通过 ps 注意到它的 PID 与 shell 中显示的不同。如果不在后台执行它,我会得到一个额外的进程,即 shell 的进程 (/bin/sh)。 我怎样才能得到该进程的真实PID? 有没有最好的方法来终止该函数内启动的进程? 谢谢!

最佳答案

我目前的方法如下:

  • 将 Express 引导进程封装在一个函数内,该函数返回用于使服务器监听请求的 httpServer 实例。这是 beforeAll 钩子(Hook)的一个很好的例子。
  • 使用前面的引用在 afterAll 中关闭服务器。

另一种选择(有点棘手),可能是在所有测试开始时启动服务器一次并在结束时关闭它:

  • 直接生成 Node 进程,而不是通过 npm
  • 将进程 ID 存储在临时 mongo 集合中(但可以是任何内容)
  • 在拆卸过程中,我检索 PID,然后执行 process.kill(PID, "SIGTERM")

关于node.js - 在 jest 拆解中杀死一个 Node.js 服务器(在 jest 的安装钩子(Hook)中启动),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55287387/

相关文章:

node.js - 我应该如何排除 electron-packager 中的所有 node_modules

javascript - 从 Node.js 调用 Scala.js 的正确方法是什么?

node.js - 使用 node.js 运行 c 程序并获取响应

ipc - Node-IPC从服务器向客户端发送消息

javascript - 如何在node.js中杀死child_process——req.on close

javascript - 如何使用 webpack 构建 requirejs 应用程序?

node.js - 按标题而非 ID 搜索 MongoDB

node.js - 尝试发布交易时出现 422 错误

Bash等待不起作用

c - 为什么这段带有 fork() 的代码只产生一个输出?