Node.js 如何作为子进程运行/关闭http服务器

Node.js 如何作为子进程运行/关闭http服务器,node.js,child-process,Node.js,Child Process,我们有一个与(Node.js)HTTP服务器交互的应用程序。为了测试API调用,我们创建了一个测试HTTP服务器,该服务器与应用程序配合良好。我们所做的所有调用都按照应用程序的预期工作 最近,我们一直在尝试自动化这些API调用的测试。我们想出的一个策略是: 自动启动测试HTTP服务器 打电话给它 测试结束后关闭测试HTTP服务器 以下是到目前为止我们编写的第一个测试: var serverHandler = require('../../server/serverHandler.js'); d

我们有一个与(Node.js)HTTP服务器交互的应用程序。为了测试API调用,我们创建了一个测试HTTP服务器,该服务器与应用程序配合良好。我们所做的所有调用都按照应用程序的预期工作

最近,我们一直在尝试自动化这些API调用的测试。我们想出的一个策略是:

  • 自动启动测试HTTP服务器
  • 打电话给它
  • 测试结束后关闭测试HTTP服务器
  • 以下是到目前为止我们编写的第一个测试:

    var serverHandler = require('../../server/serverHandler.js');
    
    describe('Test the test server', function() {
      beforeEach(async () => {
        serverHandler.start(500, 'index.js'); // index.js: the HTTP test server.
                                              // 500: 500 ms of latency to mimic a slow response.
    
        result = await serverHandler.isRunning();
        expect(result).toEqual(true);
      });
    
      afterEach(async () => {
        serverHandler.kill();
    
        result = await serverHandler.isRunning();
        expect(result).toEqual(false);
      });
    
      test('Server is killed', async () => {
        // We could have more complex test logic here...
        serverHandler.kill();
    
        try {
          result = await serverHandler.isRunning();
          expect(result).toEqual(false);
        } catch (error) {
          expect(error).toEqual({
            error: 'server is running',
          });
        }
      });
    });
    
    其中,
    serverHandler
    如下所示:

    const spawn = require('child_process').spawn;
    const isReachable = require('is-reachable');
    
    var child = null;
    
    exports.start = (latency, path) => {
      child = spawn('node', [path, latency]);
    };
    
    exports.kill = () => {
      child.kill();
    };
    
    exports.isRunning = async () => {
      return await isReachable('http://localhost:8080');
    };
    
    正如您所看到的,到目前为止,我们只尝试在添加更多测试逻辑之前使步骤1和3起作用。遗憾的是,事实并非如此。运行此测试时,我得到以下输出:

      ● Test the test server › Server is killed
    
        expect(received).toEqual(expected) // deep equality
    
        Expected: true
        Received: false
    
          14 | 
          15 |     result = await serverHandler.isRunning();
        > 16 |     expect(result).toEqual(true);
             |                    ^
          17 |   });
          18 | 
          19 |   afterEach(async () => {
    
          at toEqual (__tests__/integration/serverIntegrationExample.test.js:16:20)
          at tryCatch (node_modules/regenerator-runtime/runtime.js:45:40)
          at Generator.invoke [as _invoke] (node_modules/regenerator-runtime/runtime.js:271:22)
          at Generator.prototype.(anonymous function) [as next] (node_modules/regenerator-runtime/runtime.js:97:21)
          at tryCatch (node_modules/regenerator-runtime/runtime.js:45:40)
          at invoke (node_modules/regenerator-runtime/runtime.js:135:20)
          at node_modules/regenerator-runtime/runtime.js:145:13
          at tryCallOne (node_modules/promise/lib/core.js:37:12)
          at node_modules/promise/lib/core.js:123:15
          at flush (node_modules/asap/raw.js:50:29)
    
    服务器似乎从未真正启动过。我知道测试服务器运行良好,因为所有调用都在应用程序中成功。我已经找到了很多关于类似问题的信息来源,但大多数信息来源似乎要么是死路一条,要么是利用了不可移植的操作系统功能,这对我们来说是不可接受的(我从Ubuntu获得了这个输出)

    此代码中的问题是什么?如何实现?还要注意的是,这是我的第一个Node.js项目,因此如果您对代码有任何建设性的建议,我们将不胜感激

    编辑 下面是
    index.js
    的代码:

    const Express = require('express');
    const multer = require('multer');
    const bodyParser = require('body-parser');
    const fs = require('fs');
    
    const labelListMock = require('./mockData');
    
    const uploadDirectory = './images';
    
    const app = Express();
    app.use(bodyParser.json());
    
    const Storage = multer.diskStorage({
      destination(req, file, callback) {
        callback(null, uploadDirectory);
      },
      filename(req, file, callback) {
        callback(null, `${file.fieldname}_${Date.now()}_${file.originalname}`);
      },
    });
    
    const upload = multer({storage: Storage});
    
    app.get('/', (req, res) => {
      res.status(200).send('You can post to /DispatchData.');
    });
    
    
    var latency = process.argv[2];
    
    if (isNaN(latency)) {
      latency = 0;
    }
    
    app.use(function(req, res, next) {
      setTimeout(next, latency);
    });
    
    
    app.get('/RetrieveTypes', (req, res) => {
      res.status(200).json(labelListMock);
    });
    
    app.post(
      '/DispatchData',
      checkUploadPath,
      upload.single('photo'),
      (req, res, next) => {
        console.log('file', req.file);
        console.log('body', req.body);
    
        res.status(200).json({
          message: 'success!',
          fileName: req.file.originalname,
          category: 'buildAILabel',
        });
      },
    );
    
    module.exports = app.listen(8080, () => {
      console.log(
        'Mock server running on http://localhost:8080 (or http:://10.0.2.2:8080 if using an emulator.)',
      );
    });
    
    
    function checkUploadPath(req, res, next) {
      fs.exists(uploadDirectory, function(exists) {
        if (exists) {
          next();
        } else {
          fs.mkdir(uploadDirectory, function(err) {
            if (err) {
              console.log('Error in folder creation');
              next();
            }
            next();
          });
        }
      });
    }
    

    index.js中有什么?另外,既然
    serverHandler.start
    没有任何
    await
    语句,为什么它是异步的呢?我已经更新了这个问题(请参见代码)。index.js是包含测试服务器的脚本。对于
    serverHandler.stard
    ,我已经更新了代码。你说得对,这是我上次测试的结果。请注意,如果没有
    async
    ,错误消息是相同的。如果没有看到index.js代码,我看不到任何问题。您确定参数或使用的端口吗?可能服务器正在向8080以外的端口打开?也许听一下
    子进程中的
    stderr
    流(您有一个例子)我添加了index.js代码。。。我会试试你的建议。