简体   繁体   English

在nodejs中创建HTTPS api并测试

[英]Create HTTPS api in nodejs and test it

I'm creating an api that should run on https.我正在创建一个应该在 https 上运行的 api。 I create the server this way:我以这种方式创建服务器:

//...
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;

With this, I am able to access the api via curl.有了这个,我就可以通过 curl 访问 api。 Then I install mocha and supertest and try this in a new ./test/test.js file, copied from a couple examples...然后我安装 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);
  })
})

But this test always fails, never reaching a console.log() in my controller.但是这个测试总是失败,永远不会到达我的控制器中的console.log() It always responds like this, whether I use HTTP or HTTPS....无论我使用 HTTP 还是 HTTPS,它总是这样响应....

1) GET /myApi respond with json: Error: expected 200 "OK", got 404 "Not Found" at Test._assertStatus (node_modules/supertest/lib/test.js:232:12) 1) GET /myApi 响应 json: 错误: 预期 200 "OK", 在 Test._assertStatus (node_modules/supertest/lib/test.js:232:12) 得到 404 "Not Found"

Am I creating the express https app incorrectly?我是否错误地创建了快速 https 应用程序? Or am I accessing it incorrectly in the test file?还是我在测试文件中错误地访问了它?

I thought that simply saying app = express();我以为只是说app = express(); in the test file looked wrong, but when I try to get the "real" app from app.js, like this...在测试文件中看起来是错误的,但是当我尝试从 app.js 获取“真正的”应用程序时,就像这样......

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

I get a different error saying that the port is already in use...我收到一个不同的错误,说该端口已被使用...

Uncaught Error: listen EADDRINUSE :::3443未捕获的错误:听 EADDRINUSE :::3443

Which I guess makes sense.我想这是有道理的。 I'm stuck.我被困住了。 Any help would be very appreciated!任何帮助将不胜感激!

Here is the a minimal working example:这是一个最小的工作示例:

app.js : 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 : controller.js

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

module.exports = {
  someFunction,
};

app.test.js : 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);
  });
});

Integration test result with coverage report:带有覆盖率报告的集成测试结果:

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 |                   |
---------------|----------|----------|----------|----------|-------------------|

The error Uncaught Error: listen EADDRINUSE :::3443 means the address is already in use.错误Uncaught Error: listen EADDRINUSE :::3443表示地址已被使用。

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

This is how you create a baseline Express application:这是您创建基线 Express 应用程序的方式:

const express = require("express");

const app = express();

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

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

EADDRINUSE is a common error, it means you have another running web server on your port. EADDRINUSE是一个常见错误,这意味着您的端口上有另一个正在运行的 Web 服务器。 You can go find that other running web server and stop it or alternatively you can change your port to another number.您可以找到其他正在运行的 Web 服务器并停止它,或者您可以将您的端口更改为另一个号码。 Once you make that change, save the file you should see the error go away.进行更改后,保存文件,您应该会看到错误消失。

Additionally, Express only cares about the Path: '/myApi/' and the Method: 'GET' , so I would check to see if I put that together correctly.此外,Express 只关心Path: '/myApi/'Method: 'GET' ,所以我会检查我是否正确地将它们放在一起。 With that said, your test can be confusing as your are describe('GET /myApi' but your Path is actually /myApi/ , they are not the same thing and if you are not careful your test will fail as a result of that detail.话虽如此,您的测试可能会令人困惑,因为您的describe('GET /myApi'但您的路径实际上是/myApi/ ,它们不是一回事,如果您不小心,您的测试将因该细节而失败.

So if the router does not see the correct incoming Path , it will not run the function, the callback function you wrote.因此,如果路由器没有看到正确的传入Path ,它将不会运行该函数,即您编写的回调函数。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM