【问题标题】:Read response output buffer/stream with supertest/superagent on node.js server在 node.js 服务器上使用 supertest/superagent 读取响应输出缓冲区/流
【发布时间】:2012-11-14 10:18:34
【问题描述】:

我正在尝试编写一个测试来检查 API 路由是否输出具有正确内容的 ZIP 文件。

我正在使用 mocha 和 supertest 进行测试,我想实际读取输出流/缓冲区,读取 zip 文件内容并查看内容是否正确。

任何想法我应该怎么做?当我尝试阅读 res.body 时,它只是一个空对象。

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

【问题讨论】:

    标签: node.js zip mocha.js superagent supertest


    【解决方案1】:

    Testing binary response with supertest 中所述,在请求中设置.responseType('blob') 将导致req.body 成为缓冲区。

    https://visionmedia.github.io/superagent/#binary

    it('test', async () => {
      await request(app)
        .get('/api/some-zip')
        .responseType('blob')
        .expect(200)
        .expect('Content-Type', /application\/zip/)
        .expect(( res) => {
          const zipEntries = new AdmZip(res.body).getEntries().map(e => e.entryName);
          expect(zipEntries).toEqual(expect.arrayContaining(['zipfile1.pdf', 'zipfile2.pdf']));
      });
    });
    

    【讨论】:

      【解决方案2】:

      我刚刚遇到了同样的情况,我需要编写一个测试来检查 zip 文件的内容。我就是这样做的。

          it('test', async function () {
              let data = '';
              const res = await request(app)
                  .get('/api/some-zip')
                  .parse((res, callback) => {
                      res.setEncoding('binary');
                      res.on('data', function (chunk) {
                          data += chunk;
                      });
                      res.on('end', function () {
                          callback(null, Buffer.from(data, 'binary'));
                      });
                  })
              const zip = new AdmZip(res.body)
              const zipEntries = zip.getEntries();
      
              expect(zipEntries[0].name).to.equal('zipfile1.pdf');
              expect(zipEntries[1].name).to.equal('zipfile2.pdf');
          });
      
      

      我使用了 async/await 语法

      【讨论】:

        【解决方案3】:

        现有的答案对我不起作用。我最终做的是:

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

        【讨论】:

          【解决方案4】:

          扩展@Beau 的答案,以下可用于获取任何二进制响应内容作为缓冲区,您可以在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();
                  });
          });
          

          【讨论】:

          • 这很好用,虽然我必须在请求中添加.buffer()
          • 使用@Nate,来自docs,“如果未启用响应缓冲(.buffer(false)),则将发出响应事件而无需等待正文解析器完成,因此响应.body 将不可用”。
          • @ZachB 所以.buffer().parse(binaryParser)?
          • @rcoup 是的,文档说,但如果没有快速测试,它似乎也可以正常工作。更长的响应可能需要它...?
          【解决方案5】:

          我认为您会想要为应用程序/zip 创建自己的解析器并使用它来获取实际的响应数据;例如,JSON 解析器是 here。一旦你得到它,你可以通过将它传递给 request.parse 来使用它;所以你的测试会变成:

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

          为了找到这个问题的答案,我主要依靠检查 superagent 测试套件。 :)

          【讨论】:

            猜你喜欢
            • 2015-03-15
            • 2015-01-09
            • 2011-08-22
            • 1970-01-01
            • 2017-12-24
            • 2012-12-25
            • 2016-10-16
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多