2012-11-26 20 views
17

Sto provando a scrivere un test che controlla se un percorso API restituisce un file ZIP con i contenuti corretti.Lettura buffer/stream di output di risposta con supertest/superagent su server node.js

Sto usando mocha e supertest per il test, e mi piacerebbe davvero leggere il flusso di output/buffer, leggere il contenuto del file zip e vedere se il contenuto è corretto.

Qualche idea come dovrei farlo? Quando provo a leggere res.body, è solo un oggetto vuoto.

request(app) 
    .get("/api/v1/orders/download?id[]=1&id=2") 
    .set("Authorization", authData) 
    .expect(200) 
    .expect('Content-Type', /application\/zip/) 
    .end(function (err, res) { 
     if (err) return done(err); 

     console.log('body:', res.body) 

     // Write the temp HTML file to filesystem using utf-8 encoding 
     var zip = new AdmZip(res.body); 
     var zipEntries = zip.getEntries(); 

     console.log('zipentries:', zipEntries); 

     zipEntries.forEach(function(zipEntry) { 
     console.log(zipEntry.toString()); // outputs zip entries information 
     }); 

     done(); 
    }); 

risposta

1

Penso che vorrai creare il tuo parser per applicazione/zip e usarlo per ottenere i dati di risposta effettivi; il parser JSON è here, ad esempio. Una volta che hai capito, puoi usarlo passandolo a request.parse; quindi il test sarebbe diventato:

request(app) 
    .get("/api/v1/orders/download?id[]=1&id=2") 
    .set("Authorization", authData) 
    .expect(200) 
    .expect('Content-Type', /application\/zip/) 
    .parse(function (res, fn) { 
    res.data = ''; 
    res.on('data', function (chunk) { res.data += chunk; }); 
    res.on('end', function() { 
     try { 
     fn(null, new AdmZip(res.data)); 
     } catch (err) { 
     fn(err); 
     } 
    }); 
    }) 
    .end(function (err, res) { 
    if (err) return done(err); 

    console.log('body:', res.body) 

    // Write the temp HTML file to filesystem using utf-8 encoding 
    var zipEntries = res.body.getEntries(); 

    console.log('zipentries:', zipEntries); 

    zipEntries.forEach(function(zipEntry) { 
     console.log(zipEntry.toString()); // outputs zip entries information 
    }); 

    done(); 
    }); 

per trovare la risposta a questa mi si affida ispezionare la suite di test superagent. :)

22

Ampliando @ risposta di Beau, il seguente può essere usato per ottenere qualsiasi contenuto della risposta binaria come un buffer che è possibile esaminare ulteriormente nel request.end():

function binaryParser(res, callback) { 
    res.setEncoding('binary'); 
    res.data = ''; 
    res.on('data', function (chunk) { 
     res.data += chunk; 
    }); 
    res.on('end', function() { 
     callback(null, new Buffer(res.data, 'binary')); 
    }); 
} 

// example mocha test 
it('my test', function(done) { 
    request(app) 
     .get('/path/to/image.png') 
     .expect(200) 
     .expect('Content-Type', 'image.png') 
     .buffer() 
     .parse(binaryParser) 
     .end(function(err, res) { 
      if (err) return done(err); 

      // binary response data is in res.body as a buffer 
      assert.ok(Buffer.isBuffer(res.body)); 
      console.log("res=", res.body); 

      done(); 
     }); 
}); 
+1

Questo funziona benissimo, anche se ho dovuto aggiungere '.buffer()' alla richiesta. – Nate

+0

Con @Nate, da [docs] (http://visionmedia.github.io/superagent/#parsing-response-bodies), "Se il buffer di risposta non è abilitato (.buffer (false)), l'evento di risposta essere emesso senza attendere che il parser del corpo finisca, quindi response.body non sarà disponibile ". – ZachB

+0

@ZachB quindi '.buffer(). Parse (binaryParser)'? – rcoup

-1

risposte esistenti non ha funzionato per me. Quello che ho finito è stato:

// parses response.body buffer into a data object 
const parsePDF = response => { 
    return new Promise((resolve, reject) => { 
    // code that parses response.body as buffer 
    // and calls resolve(data); when done 
    // or reject(err); on error 
    }) 
}; 

const binaryParser = require('superagent-binary-parser'); 

// test snippet 
request(app) 
    .get('/some/api/returning/pdf') 
    .expect(200) 
    .expect('content-type', 'application/pdf') 
    .parse(binaryParser) 
    .buffer() 
    .then(parsePDF) 
    .then((pdf) => { 
     chai.expect(pdf.pages.length).to.be.equal(5); 
    })