2017-07-03 2 views
0

Ich habe einen normalen Komponententest für meine REST API mit Chai-http. Es wird mit Fehler folgendeChai http - doppeltes Callback-Problem

warn: double callback! 
error: { SyntaxError: Unexpected token { in JSON at position 58 
    at Object.parse (native) 
    at IncomingMessage.<anonymous> (E:\projects\node_modules\chai-http\node_modules\superagent\lib\node\parsers\json.js:8:35) 
    at emitNone (events.js:91:20) 
    at IncomingMessage.emit (events.js:185:7) 
    at endReadableNT (_stream_readable.js:974:12) 
    at _combinedTickCallback (internal/process/next_tick.js:80:11) 
    at process._tickCallback (internal/process/next_tick.js:104:9) 
    rawResponse: '{"books":[],"count":0,"page":1,"pages":0,"pageSize":10}{"books":[],"count":0,"page":1,"pages":0,"pageSize":10}', 
    statusCode: 200, 
    response: undefined } 

Wie Sie sehen können, die rawResponse dupliziert wird aufgrund der der Test ausfällt. Ich debuggte den Code, und der Controller-Code wird genau einmal mit der richtigen Ausgabe aufgerufen. Kann aber nicht verstehen, warum dieser Fehler auftritt.

Es folgt der Testcode

// some code to mock mongoose with mockgoose 
.... 
.... 

let server = require('../../../server'); 
let should = chai.should(); 
chai.use(chaiHttp); 


describe.only('Books',() => { 
    describe('/GET book',() => { 
     it('it should GET all the books', (done) => { 
     chai.request(server) 
      .get('/api/books') 
      .end((err, res) => { 
       console.log(res); 
       res.should.have.status(200); 

       done(); 
      }).catch(function(err){ 
       console.error(err); 
       done(err); 
      }); 
     }); 
    }); 
}); 

Antwort

6

Sie Mischen von zwei Arten von Asynchron-Handhabung: .end/.catch statt entweder mit .then/.catchoder.end

Da ein Fehler ist, beide .end() (mit der Das erste Argument, err, set) und .catch() werden aufgerufen, was dazu führt, dass der Rückruf done zweimal aufgerufen wird.

Hier ist eine Lösung .then/.catch verwenden, kombiniert mit Mokka-interner Versprechen Unterstützung (nicht done verwenden):

it('it should GET all the books',() => { 
    return chai.request(server) 
     .get("/api/books") 
     .then(res => { 
     console.log(res); 
     res.should.have.status(200); 
     }) 
     .catch(err => { 
     console.error(err); 
     throw err; // Re-throw the error if the test should fail when an error happens 
     }); 
}); 

Und mit .end:

it('it should GET all the books', done => { 

    chai.request(server) 
     .get("/api/books") 
     .end((err, res) => { 
     if (err) return done(err); 
     console.log(res); 
     res.should.have.status(200); 
     done(); 
     }); 

}); 
+0

Ja, und denken Sie daran, mit dem Versprechen Mokka tut brauche die Fangmeldung nicht! – jesusgn90

+0

@ jesusgn90, es sei denn, der Test erwartet tatsächlich einen Fehler: D – robertklep

+0

Mocha erkennen Versprechen Ablehnung selbst – jesusgn90