2016-08-25 2 views
0

ich derzeit Mokka 2.5.3, 2.0.0 Supertest verwenden, Knex 0.11.10, restify 4.1.1 und 3.1.4 sqlite3.Warum Mocha Timeout bei Verwendung mit Restify und Knex?

Ich habe den folgenden sehr einfachen restify Server:

const restify = require('restify'); 
const knex = require('knex')({ 
    client: 'sqlite3', 
    connection: { 
    'filename': 'test.db' 
    } 
}); 

const app = restify.createServer(); 

app.get('/', (req, res, next) => { 
    knex.select().from('nonexistent_table') 
    .then((rows) => { 
    return res.json(rows); 
    }) 
    .catch((err) => { 
    return res.send('error'); 
    }); 
}); 
module.exports = app; 

Der unten Test wird den Test verursacht bei 2000ms Timeout statt Fehlern:

const assert = require('assert'); 
const supertest = require('supertest'); 
const app = require('./app'); 

describe('GET /', function() { 

    it('should not timeout', function (done) { 
    supertest(app) 
    .get('/') 
    .end(function(err, res) { 
     assert(false); 
     done(); 
    }); 
    }); 
}); 

Wenn der Aufruf von Knex statt erfüllen Wenn der Test abgelehnt wird, schlägt der Test fehl und es tritt keine Zeitüberschreitung auf. Die Zeitüberschreitung tritt nur auf, wenn der Knex-Aufruf abgelehnt wird.

Hat jemand Gedanken auf, was könnte das Timeout statt eines richtigen Ausfall verursachen?

EDIT: ich dies so weit ausgetestet habe, wie ich konnte, und es scheint, das Timeout passiert, wenn Mokka einen Stacktrace zu erzeugen versucht.

+0

Siehe meine Antwort [hier] (http://stackoverflow.com/a/39103469/893780): weil die Behauptung wirft einen Fehler, 'done' nie _and_ der Fehler genannt wird nie gefangen. – robertklep

+1

@robertklep danke, aber ich bin mir nicht sicher, dass das die richtige Antwort aus zwei Gründen ist. Wenn knex aufgelöst wird, schlägt der Test normalerweise fehl. Da ich im Test gerade "Assert (False)" mache, sollte die Art des Fehlers nicht von der Antwort des Restify-Servers oder dem Ergebnis von Knex abhängen, aber irgendwie funktioniert es! Zweitens, wenn ich einen Mocha-Test schreibe, der keinen asynchronen HTTP-Aufruf ausführt und einfach einen Fehler ausgibt, wird der Test zu Recht fehlschlagen und kein Timeout, obwohl ich nie 'done()' aufrufen werde. Dies führt mich zu der Annahme, dass das Werfen von Fehlern/fehlgeschlagenen Behauptungen der normale Weg ist, dass Mocha-Tests fehlschlagen. – harrymonster

Antwort

0

versuchen, die erste Zeile zu ändern, mit: bluebird.resolve(knex.select().from('nonexistent_table'))

Sie müssen auch ‚drossel‘ auf erfordern. Es wird ein Problem lösen ein Ihnen einige Kontext über einen Fehler

ich das Problem mit ausgewählten denken: Sie vergessen, ein Argument

+0

Gerade beide dieser möglichen Lösungen ausprobiert und sie haben das Problem nicht behoben. Das heißt, ich habe 'knex.select ('*'). From ('nonexistent_table') 'versucht und auch' bluebird.resolve (knex.select ('*') from ('nonexistent_table'))' '. – harrymonster

1

supertest verwendet superagent hinter den Kulissen und superagent unterstützt verspricht. (Suche nach .thenhere.) So können Sie .then statt .end verwenden und nur das Versprechen, zurückzukehren, anstatt done verwenden:

it('should not timeout', function() { 
     return supertest(app) 
      .get('/') 
      .then(function(res) { 
       assert(false); 
      }); 
    }); 

Wenn ich den obigen Code mit dem Rest des Codes in der Frage, mich dann bekomme einen richtigen Fehler.

Wie, warum done hat nicht funktioniert, ist es mir nicht klar. Es kann sein, dass supertest oder superagent Ausnahmen verschluckt, die in dem an .end() übergebenen Rückruf ausgelöst werden. Wenn Ausnahmen verschluckt werden, kann Mocha sie nicht erkennen. Sie müssten dann die durch die fehlerhafte Behauptung hervorgerufene Ausnahme selbst abfangen und an done übergeben. Ich ziehe es vor, Versprechungen zu verwenden.

+0

Meine Vermutung ist, dass der 'end' Rückruf, in dem fehlerhaften Fall von _inside_ der' .catch() 'in den Route-Handler aufgerufen wird, die die Behauptung Fehler schlucken _and_ verhindern' done' von genannt zu werden. – robertklep

+0

Ich stimme zu, Versprechen können die richtige Richtung sein, um hier zu gehen.Aber ich fange an zu denken, dass dies ein Bug im Knoten sein könnte, da, wenn ich eine Exception innerhalb des '.end()' Callbacks erstelle, aber knex nicht auf der Serverseite aufgerufen wird, der Test normalerweise fehlschlägt. Das sagt mir, dass Superaktivität keine Ausnahmen verschlingt. Hier läuft noch etwas anderes, und ich denke, es hat etwas damit zu tun, dass Mocha einen Stacktrace generiert. Ich werde meine Frage mit meinen Ergebnissen dazu aktualisieren. – harrymonster

+0

Eine andere Theorie ist, dass, weil der "catch" keine Fehlerantwort sendet, eine interne "Superagenten" -Verkundung aufgelöst werden kann, so dass der nachfolgende Assertionsfehler ihn nicht mehr zurückweisen kann. – robertklep

Verwandte Themen