13

Node.js 相当新

制作了一个运行服务器进程并提供文件的应用程序(不使用 express 或任何框架),现在我正在尝试对其进行单元测试。

我正在尝试为此使用 mocha 测试...我打算启动我的服务器进程,然后针对它运行请求以测试预期结果(统计代码、正文内容等)

但是它不能正常工作,所有请求都无法连接到服务器......我很确定问题是因为节点正在运行一个进程循环,当查询运行时服务器没有“在后台”运行或者可能在发出请求时服务器尚未运行(启动 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)
4

3 回答 3

7

在您收到服务器触发的“侦听”事件之前,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 的文档

于 2012-08-20T01:15:17.523 回答
1

还必须处理成块出现的身体,这是最后的工作,以防对其他人有帮助:

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();
    });
});

});
于 2012-08-20T04:48:04.073 回答
1

使用超测

这是一个使用SuperTestMocha的完整而直接的示例

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 代理更容易使用)。
  • 将您的服务器绑定到一个临时端口,因此无需跟踪端口(如果需要,您仍然可以手动进行)。
  • 使用适用于Mocha(或任何其他测试框架)的含糖期望方法。
于 2015-04-30T13:11:40.397 回答