Read response output buffer/stream with supertest/superagent on node.js server

后端 未结 3 1102
粉色の甜心
粉色の甜心 2021-02-05 07:15

I am trying to write a test that checks whether an API route outputs a ZIP file with the correct contents.

I am using mocha and supertest for testing, and I would like t

相关标签:
3条回答
  • 2021-02-05 07:43

    I think you'll want to create your own parser for application/zip and use that to get at the actual response data; the JSON parser is here, for example. Once you've got that you can use it by passing it to request.parse; so your test would become:

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

    To find the answer to this I mostly relied on inspecting the superagent test suite. :)

    0 讨论(0)
  • 2021-02-05 07:46

    Existing answers didn't work for me. What I ended up doing was:

    // 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);
        })
    
    0 讨论(0)
  • 2021-02-05 07:59

    Expanding on @Beau's answer, the following can be used to get any binary response content as a Buffer which you can examine further in 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();
            });
    });
    
    0 讨论(0)
提交回复
热议问题