Подтвердить что ты не робот

Попытка протестировать серверный процесс Node.js с использованием Mocha

Довольно неожиданно для Node.js

Создал приложение, которое запускает процесс сервера и обслуживает файлы (не использует явные или какие-либо фреймворки). Теперь я пытаюсь unit test его.

Я пытаюсь использовать тест мокки для этого... Я намеревался запустить свой серверный процесс, а затем запустить запросы против него, чтобы проверить ожидаемые результаты (код статистики, содержимое тела и т.п.)

Однако он не работает должным образом, все запросы не подключаются к серверу... Я уверен, что проблема связана с тем, что node - это juts, выполняющий один цикл процесса, сервер не работает "в фоновом режиме" пока запущены запросы или, возможно, сервер еще не запущен (запущен ASYNC) во время выполнения запроса?

В любом случае мне было интересно, что было правильным способом проверить это, я полагаю, что либо мне нужно, чтобы сервер работал в фоновом режиме (например, разветвленный процесс), и/или, может быть, мне нужно найти способ подождать серверный процесс сначала "вверх", но не уверен, как это сделать.

Или, по крайней мере, рекомендации по тестированию такого серверного процесса (с Mocha или другим).

Спасибо.

Вот пример тестового кода (обновлен с оригинального вопроса)

var server = new Server302('./fixture/');

var instance;

describe('Tests', function() {

before(function(done) {
     instance = http.createServer(function(request, response) {
        console.log(request.url);
        server.serve(request, response);
    }).listen(8000);
    instance.on("listening", function() {
        console.log("started");
        done();
    });
});

after(function(done){
  instance.close();
  console.log("stopped");
  done();
});

it("Should fetch test.html", function(done) {
    console.log("test1");
    http.get("http://localhost:8000/", function(res) {
        res.on('data', function(body) {
            console.log(body)
            expect(body).toEqual("test");
            done();
        });
    })
});

Кажется, что выполнить Выполнение по порядку, но все еще не удается с ошибкой соединения, тогда как он работает при проверке вручную с помощью браузера:

started
test1
․․․stopped


  ✖ 1 of 1 tests failed:

  1) Tests Should fetch test.html:
  Error: connect ECONNREFUSED
  at errnoException (net.js:670:11)
  at Object.afterConnect [as oncomplete] (net.js:661:19)
4b9b3361

Ответ 1

В before не вызывайте done, пока не получите событие "прослушивания", запущенное сервером.

before(function(done) {
    instance = http.createServer(function(request, response) {
        console.log(request.url);
        server.serve(request, response);
    }).listen(8000);
    instance.on("listening", function() {
        console.log("started");
        done();
    });
});

Это должно гарантировать, что ваши тестовые подключения не начнутся до того, как сервер будет готов.

См. также документацию для server.listen

Ответ 2

Также приходилось иметь дело с телом, входящим в куски, вот последняя вещь, которая работает, в случае, если кто-то помог:

var Server302 = require('../lib/server302.js'),
http = require('http'),
assert = require("assert");

var server = new Server302('./fixture/');

var instance;

describe('Tests', function() {

before(function(done) {
    instance = http.createServer(function(request, response) {
        server.serve(request, response);
    }).listen(8100);
    instance.on("listening", function() {
        done();
    });
});

after(function(done) {
    instance.close();
    done();
});

it("Should fetch test.html", function(done) {
    console.log("test1");
    var body = "";
    http.get({host: "localhost", port:8100, path: "/"}, function(res) {
        res.on('data', function(chunk) {
            // Note: it might be chunked, so need to read the whole thing.
            body += chunk;
        });
        res.on('end', function() {
            assert.ok(body.toString().indexOf("<a href='/dummy.txt'>") !== -1);
            assert.equal(res.statusCode, 200);
            done();
        });
    })
});

it("Should fetch dummy.txt", function(done) {
    http.get({host: "localhost", port:8100, path: "/dummy.txt"}, function(res) {
        res.on('data', function(body) {
            assert.equal(res.statusCode, 200);
            assert.ok(body.toString().indexOf("test") === 0);
            done();
        });
    });
});

it("Should get 404", function(done) {
    http.get({host: "localhost", port:8100, path: "/qwerty"}, function(res) {
        assert.equal(res.statusCode, 404);
        done();
    });
});

});

Ответ 3

Использование SuperTest

Вот полный и простой пример, используя SuperTest и Mocha:

var server = new Server302('./fixture/');
var request = require('supertest');

describe('Tests', function() {
  it('Should fetch test.html', function(done) {
    request(server)
      .get('/')
      .expect('test', done);
  });
});

SuperTest позволяет:

  • Запросите ваш сервер, используя SuperAgent (гораздо проще в использовании, чем низкий уровень http agent).
  • Связать ваш сервер с эфемерным портом, поэтому нет необходимости отслеживать порты (вы все равно можете сделать это вручную, если это необходимо).
  • Используйте методы sugary expect, которые работают с Mocha (или любой другой тестовой среды).