在jest拆卸中杀死node.js服务器(在jest的安装钩子中启动)

在jest拆卸中杀死node.js服务器(在jest的安装钩子中启动),node.js,child-process,Node.js,Child Process,我使用它作为测试库,在它的内部(在所有测试之前执行),我使用一个子进程在某个端口上启动测试服务器。 设置代码基本上执行NPM命令: “运行服务器测试”:“NODE_ENV=test server_PORT=3001 NODE src/index.js&”, “测试”:“节点\环境=测试服务器\端口=3001 jest--detectOpenHandles--forceExit”, 这是设置功能: const{spawn}=require(“子进程”) module.exports=异步函数设置

我使用它作为测试库,在它的内部(在所有测试之前执行),我使用一个子进程在某个端口上启动测试服务器。 设置代码基本上执行NPM命令:

“运行服务器测试”:“NODE_ENV=test server_PORT=3001 NODE src/index.js&”,
“测试”:“节点\环境=测试服务器\端口=3001 jest--detectOpenHandles--forceExit”,
这是设置功能:

const{spawn}=require(“子进程”)
module.exports=异步函数设置(){
返回新承诺((解决、拒绝)=>{
const testServerProcess=spawn(“npm”、[“运行”、“运行服务器测试”])
testServerProcess.on(“错误”,err=>{
console.log(“启动子流程失败”,错误)
拒绝(错误)
})
testServerProcess.stdout.on(“数据”,数据=>{
if(data.toString().startsWith(“阿波罗服务器”)){
console.log(`\n测试服务器使用PID${testServerProcess.PID}`运行)
解析(真)
}
})
testServerProcess.stderr.on(“数据”,数据=>{
console.error(`stderr:${data}`)
拒绝(新错误(data.toString()))
})
})
}
请注意,我在后台使用
&
执行命令。当Jest完成它的工作时,我注意到它的PID与shell中显示的PID不同。没有在后台执行它,我得到了一个额外的进程,shell的进程(
/bin/sh
)。 我怎样才能得到这个过程的真实PID? 有没有最好的方法来终止该函数内部启动的进程?
谢谢

您可以在服务器上创建启动和停止方法。这样,您就不必担心流程的分叉

我以express为例

app.js

const start = async (callback => { 
  await database.connect();
  server.listen(config.port, config.ip, () => {
    callback();
  });
};

const stop = (callback => {
  server.close(async () => {
    await database.disconnect();
    callback();
  });
};
app.test.js

const server = require('./path/to/server');

beforeAll(async () => {
  try {
    await server.start();
  } catch (error) {
    // if the server doesn't start up or the seeding fails, just
    // exit the process ASAP
    process.exit(1);  
  }
});

afterAll(done => {
  server.stop(done);
});

我目前的做法如下:

  • 将快速引导过程封装在一个函数中,该函数返回用于使服务器侦听请求的
    httpServer
    实例。这对于之前的
    hook是一个很好的例子
  • 使用前面的参考关闭
    中的服务器
另一种选择(有点棘手),可能是在所有测试开始时启动服务器一次,然后在测试结束时关闭它:

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