используя chai-http с swagger-express-mw - PullRequest
0 голосов
/ 12 сентября 2018

У меня проблемы с настройкой этих интеграционных тестов для работы с swagger-express-mw, который является промежуточным программным обеспечением для swagger express.

app.js:

'use strict';

var SwaggerExpress = require('swagger-express-mw');
var SwaggerUi = require('swagger-tools/middleware/swagger-ui');
var SwaggerValidator = require('swagger-tools/middleware/swagger-validator')
var mongoose = require('mongoose');
var app = require('express')();
var config = require("./config/mongoConfig");
var logConfig = require("./config/loggerConfig");
var morgan = require('morgan');
var fs = require('fs');
var jwt = require('jsonwebtoken');
var consul = require('./api/helpers/consul');
var helpers = require('btis.helpers');
new consul.ConsulClient().getKeys(['databases/mongo/devhost', 'databases/mongo/lookup/dbname'], (err, result) => {  

  mongoose.connect(result.devhost.Value + "/" + result.dbname.Value);

  var config = {
    appRoot: __dirname // required config
  };

  SwaggerExpress.create(config, function (err, swaggerExpress) {
    if (err) { throw err; }

    // add custom tokens to morgan
    morgan.token('fdate', () => {
      return new Date().toISOString()
        .replace(/T/, ' ')
        .replace(/Z/, '');
    })

    morgan.token('loglevel', () => {
      return logConfig.requestLogLevel;
    })

    morgan.token('line', () => {
      return 0;
    })

    morgan.token('correlationid', (req) => {
        var cid = getIgnoreCase(req.headers,'X-Correlation-ID');
        if (!cid) {
            cid = new helpers.CorrelationIdProvider(req).GetCorrelationIds();
        }
      return cid;
    })

    morgan.token('message', (req) => {
      return  `Static ${req.path} Logged`;//req.body;
    })

    // format request/response logs
    // ex: 2017-07-21 14:06:58.348|DEBUG|/states|0|31f4c6cf-dbdd-46b9-9c1c-eb09adba3e1a|test message
    var format = (tokens, req, res) => {
      return [
        tokens.fdate(),
        tokens.loglevel(),
        tokens.url(req),
        tokens.line(),
        tokens.correlationid(req),
        tokens.message(req)
      ].join(logConfig.delimiter)
    };

    // install middleware
    app.use(morgan(format));
    app.use(morgan(format, {stream: fs.createWriteStream('/var/log/microservices/access.log', {flags: 'a'})}));

    // install swgger-ui
    app.use(SwaggerValidator({validatorUrl: undefined, validateResponse: false}));
 // install swgger-ui
    app.use(SwaggerUi(swaggerExpress.runner.swagger));


    swaggerExpress.register(app);

    app.use(errorSwaggerHandler);

    var port = process.env.PORT || 3000;

    app.listen(port);

    function getIgnoreCase(obj, key ){
      if (obj[key]) {
          return obj[key];
      }
      if (obj[key.toLowerCase()]) {
          return obj[key.toLowerCase()];
      }
      return null;
  }

    if (swaggerExpress.runner.swagger.paths['/hello']) {
      console.log('try this:\ncurl http://127.0.0.1:' + port + '/hello?name=Scott');
    }
  });
})

/*
    Intercepting errors detected from the swagger validation. We can return customised errors based on the
    operationId and the err.code. Could move this into it's own js file and export it.
    In the future as the api changes, this may become more difficult to manage. Perhaps default swagger error handling
    should be considered.
 */
function errorSwaggerHandler(err, req, res, next) {
  let operationId = "";

  if (req.swagger.operation && req.swagger.operation.operationId)
    operationId = req.swagger.operation.operationId
  else
    operationId = req.swagger.apiPath;

  let originalResponse = "";

  if(err && err.originalResponse)
    originalResponse = err.originalResponse.toString('utf8');

  console.log('Error code: ', err.code);
  console.log('Error message: ', err.message);
  console.log('Verify swagger response definition for request operation: ', operationId);
  console.log('Original response: ', originalResponse);

  var parsedResponse;

  try{

    parsedResponse = JSON.parse(originalResponse);

  }catch(e){

    parsedResponse = originalResponse;

  }

  let swaggerErrorResponse = {
    message: err.message,
    errorCode: err.code,
    errors: err.results,
    originalResponse: parsedResponse
  };

  res.status(500).json(swaggerErrorResponse);
}

module.exports = app; // for testing

raterpackages.test.ts

import * as mocha from 'mocha';
import * as chai from 'chai';
var chaiHttp = require('chai-http');
let should = chai.should();
let app = require('../../app.js')
let token = 'removed for security reasons'

chai.use(chaiHttp)

describe('Testing for 3 packages for each of the 44 QAA states', () => {
    describe('GET /raterpackages?stateName=AL&effectiveDate=2018-12-01', () => {
        it('should return 3 packages', (done) => {
            chai.request(app)
                .get('/raterpackages?stateName=AL&effectiveDate=2018-12-01')
                .set('x-access-token', token)
                .end((err,res) => {
                    if (err) {
                        console.log(JSON.stringify(err));
                        done(err)
                    }
                    else {
                        console.log(JSON.stringify(res));
                        res.should.have.status(200);
                        res.body.should.be.a('array');
                        done()
                    }
                })
        })
    })
})

Каждый раз, когда я запускаю это, chai-http, кажется, назначает случайный порт серверу, поэтому в результате получается статус 404

Я думаю, это потому, что app.js слушает внутри асинхронной операции SwaggerExpress.create, но если я пытаюсь заменить chai.request (app) на chai.request ('http://localhost:3000'),, я получаю

Ошибка: подключить ECONNREFUSED 127.0.0.1:3000

Если я сначала попробую запустить приложение, а затем запустить тесты, я получу

Uncaught Error: прослушать EADDRINUSE ::: 3000

но дамп console.log содержит тело ответа.

Как мне решить эти проблемы?

...