在nodejs中创建HTTPS api并对其进行测试

时间:2016-02-22 17:09:30

标签: javascript node.js mocha supertest

我正在创建一个应该在https上运行的api。我用这种方式创建服务器:

//...
var app = express();
app.use(passport.initialize());

// do config, like app.use(express.bodyParser());, etc

var myController = require('../app/controllers/myController');  
app.get('/myApi/', myController.someFunction);

var useHTTPS = true;

if (useHTTPS) {
    var https = require('https');
    var fs = require('fs');
    var options = {
      key: fs.readFileSync('./config/key.pem'),
      cert: fs.readFileSync('./config/cert.pem')
    };
    var port = 3443;
    https.createServer(options, app).listen(port);
    console.log('started HTTPS on port ' + port);
} else {
    var port = 3000;
    app.listen(port);
    console.log('started HTTP on port ' + port);
}

module.exports = app;

有了这个,我可以通过curl访问api。然后我安装mocha和supertest并在一个新的./test/test.js文件中尝试这个,从几个例子中复制......

var assert = require('assert');    
var request = require('supertest')
  , express = require('express');

var app = express();

describe('GET /myApi', function(){
  it('respond with json', function(done){
    request(app)
      .get('/myApi/')
      .expect(200, done);
  })
})

但是这个测试总是失败,从未在我的控制器中达到console.log()。它总是这样响应,无论我使用HTTP还是HTTPS ....

  

1)GET / myApi用json回复:        错误:预计200“OK”,得到404“未找到”        在Test._assertStatus(node_modules / supertest / lib / test.js:232:12)

我是否错误地创建了快速https应用?或者我是否在测试文件中错误地访问了它?

我认为只是简单地说测试文件中的app = express();看起来不对,但当我尝试从app.js获取“真正的”应用时,就像这样...

// in ./test/test.js
var app = require("../app.js");

我得到一个不同的错误,说端口已经在使用......

  

未捕捉错误:听EADDRINUSE ::: 3443

我认为这是有道理的。我被卡住了。任何帮助将非常感谢!

2 个答案:

答案 0 :(得分:0)

这是一个最小的工作示例:

app.js

const express = require("express");
const controller = require("./controller");

const useHTTPS = true;
const app = express();
app.get("/api/", controller.someFunction);

let server;
if (useHTTPS) {
  const https = require("https");
  const fs = require("fs");
  const path = require("path");

  const options = {
    key: fs.readFileSync(path.resolve(__dirname, "./config/key.pem")),
    cert: fs.readFileSync(path.resolve(__dirname, "./config/cert.pem")),
  };
  const port = 3443;
  server = https.createServer(options, app);
  server.listen(port);
  console.log("started HTTPS on port " + port);
} else {
  const port = 3000;
  server = app.listen(port);
  console.log("started HTTP on port " + port);
}

module.exports = server;

controller.js

function someFunction(req, res) {
  res.sendStatus(200);
}

module.exports = {
  someFunction,
};

app.test.js

const request = require("supertest");
const app = require("./app");

describe("GET /api", function() {
  after((done) => {
    app.close(done);
  });
  it("respond with json", function(done) {
    request(app)
      .get("/api/")
      .expect(200, done);
  });
});

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

started HTTPS on port 3443


  GET /api
    ✓ respond with json


  1 passing (37ms)

---------------|----------|----------|----------|----------|-------------------|
File           |  % Stmts | % Branch |  % Funcs |  % Lines | Uncovered Line #s |
---------------|----------|----------|----------|----------|-------------------|
All files      |    88.89 |       50 |      100 |    88.89 |                   |
 app.js        |    83.33 |       50 |      100 |    83.33 |          23,24,25 |
 app.test.js   |      100 |      100 |      100 |      100 |                   |
 controller.js |      100 |      100 |      100 |      100 |                   |
---------------|----------|----------|----------|----------|-------------------|

错误Uncaught Error: listen EADDRINUSE :::3443表示该地址已被使用。

源代码:https://github.com/mrdulin/mocha-chai-sinon-codelab/tree/master/src/stackoverflow/35559645

答案 1 :(得分:0)

这是创建基准Express应用程序的方式:

const express = require("express");

const app = express();

app.get("/", (req, res) => {
  res.send("howdy!");
});

app.listen(3000, () => {
  console.log("Listening");
});

EADDRINUSE 是一个常见错误,这意味着您的端口上有另一个正在运行的Web服务器。您可以找到其他正在运行的Web服务器并停止它,也可以将端口更改为另一个数字。进行更改后,保存文件即可看到错误消失。

另外,Express只关心路径: '/myApi/'方法: 'GET',所以我要检查是否放置了正确地结合在一起。话虽如此,您的测试可能会像describe('GET /myApi'一样令人困惑,但是您的 Path 实际上是/myApi/,它们不是一回事,如果您不小心,测试会由于这些细节而失败。

因此,如果路由器看不到正确的传入路径,它将不会运行您编写的回调函数。