koa/supertest 在多个 post 请求上挂起

koa/supertest hangs on multiple post requests

如前所述,我正在尝试使用 supertest 在 koa 服务器上执行多个 post 请求。正如您在下面的代码中看到的那样。通过

执行脚本时
DEBUG=koa* mocha --harmony_destructuring --sort --require co-mocha --timeout 0 "test.js"

它只是在调度第二个 post 请求时挂起。与服务器的第二个连接以某种方式永远保持打开状态(请参阅 leaked-handles 调试输出)。 GET 请求处理得很好。我发现如果我执行以下任一操作,它会以某种方式起作用:

我真的很想了解为什么会这样,以及我在这里做错了什么,因为我认为引入那个古怪的 do-not-yield-middleware-workaround 是很糟糕的。

    'use strict';

    require('leaked-handles').set({
        fullStack: true,
        timeout: 5000,
        debugSockets: true
    });

    var http = require('http');
    var app = require('koa')();
    var router = require('koa-router');
    var body = require('koa-body')();
    var compose = require('koa-compose');

    var www = function () {
        var r = router();
        r.get('/test', function * (next) {
            this.body = 200;
            yield next;
        });
        r.post('/test', body, function * (next) {
            console.log(this.request.body);
            this.body = {status: 200};
            yield next;
        });

        app.use(compose([
            r.routes(),
            r.allowedMethods()
        ]));

        // app.use(function * last (next) {/* do not yield */}); // <----

        var server = http.createServer(app.callback());
        return server;
    };


    var supertest = require('supertest');
    var expect = require('chai').expect;

    describe('testing server', () => {

        var agent, server;
        var data = {test: 123};

        beforeEach(function () {
            server = www();
            agent = supertest(server.listen());
        });

        afterEach(function (done) {
            server.close(done);
        });

        describe('get', () => {
            it('returns ok', (done) => {
                agent.get('/test').expect(200, done);
            });
            it('returns ok', (done) => {
                agent.get('/test').expect(200, done);
            });
        });

        describe('post 1', () => {
            it('returns ok', (done) => {
                agent.post('/test')
                     .send(data)
                     .expect(200, done);
            });
        });

        describe('post 2', () => {
            it('returns ok', (done) => {
                agent.post('/test')
                     .send(data)
                     .expect(200, done);
            });
        });

    });

好的,正如上面评论中提到的,我发现了问题所在。 它基本上是这一行:

    var app = require('koa')();

koa 本身必须在 www 函数中实例化,即

    var koa = require('koa');
    ...
    var www = function () {
        var app = koa();
        ...
    }
    ...

虽然我仍然不确定究竟是什么导致了该行为,但这可以正确修复它。