Chai Http Post: сохранить сущность в mongodb Ошибка: прочитать ECONNRESET - PullRequest
1 голос
/ 20 марта 2019

Я пишу тест для маршрута, который сохраняет объект в mongodb.Маршрут работает нормально при использовании почтальона, но не запускается при запуске http-теста chai.

Выдается либо ошибка:

Ошибка: прочитайте ECONNRESET

Или иногда:

Ошибка: сокет зависает.

Я не понимаю, что делаю неправильно, я был бы очень признателен, если бы кто-то мог мне помочь или указать мнепо направлению.Cheers

Файл сервера:

const express = require('express');
const database = require('./controller/databaseController');
const router = require('./routes/router');
const bodyParser = require('body-parser');

const app =  express();
const port = 3000;

app.use(bodyParser.json());

app.use("/", router);

database.connect();

app.listen(port, () => {

    console.log( "serveur launched, listening on port " + port );
    console.log("environment : " + app.settings.env);

});

//export app for testing purpose
module.exports = app;

Код маршрута:

router.post('/savePharmacie', (req, res) => {

    var pharmacie = new PharmacieModel(req.body);

    pharmacie.save((err, doc) => {

        if(err){

            res.writeHead(500, {"Content-Type": "application/json"});
            res.json(err);
            res.end();

        }else{

            res.writeHead(200, {"Content-Type": "application/json"});
            res.json(doc);
            res.end();

        }

    });

});

Тестовый код:

describe('save to database', () => {

    it('save one to database', (done) => {

        chai.request(app)
        .post('saveData/savePharmacie')
        .send(pharmacieMockup)
        .end((err, resp,  body) => {

            if(err){

                console.log("error : " + err);

                done(err);

            }else{

                var response = res.body;     
                console.log("response : " + response);               
                var expected = [pharmacieMockup];                    

                response.should.be.a('array');
                expect(response[0]).to.deep.include(expected[0]);

                done();


            }

        });


    });

    after((done) => {

        PharmacieModel.deleteMany({});
        done();

    });


});

Объект pharmacieMockup являетсяфиктивный объект json, который следует схеме mongoose.

app объект ссылается на экземпляр экспресс-сервера.

Протестированный маршрут ('saveData / savePharmacie') описан в верхнем (router.post).

1 Ответ

1 голос
/ 27 марта 2019

Ваша первая проблема вызвана функцией app.listen: это асинхронная функция, поэтому при импорте файла основного сервера вы не можете быть уверены, что он запущен.

Затем chaihttp lib Документация говорит:

В качестве основы для вашего запроса вы можете использовать функцию (например, приложение для экспресс или подключения) или сервер node.js http (s).Если сервер не работает, chai-http найдет подходящий порт для прослушивания для данного теста.

Итак, я предлагаю вам разделить ваше экспресс-приложение и сервер используя два файла: таким образом, вы можете импортировать ваше экспресс-приложение в свои тесты без обработки внешних асинхронных функций.

Это минимальный пример предлагаемой структуры:

Файл app.js:

const app = express();
app.get('/', function(req, res) {
  res.status(200);
});
module.exports = app

Файл bin/app (файл без расширения):

#!/usr/bin/env node

// the above line is required if you want to make it directly executable
// to achieve this you need to make it executable using "chmod +x bin/app"  from you shell, but it's an optional only required if you want to run it using "./bin/app" without an npm script.

var app = require('../app');
var http = require('http');

app.set('port', process.env.PORT || '3000');

var server = http.createServer(app);

Затем обновите файл package.json с помощью нового сценария запуска:

"scripts": {
  //...
  "start-app": "node ./bin/app",
}

Теперь вы можете запустить ваше приложение, используя npm run start-app.Ваш тестовый код должен остаться прежним, импортируя только файл app.js с командой require.

...