繁体   English   中英

如何使用supertest和jest测试图像上传(流)?

[英]How to test image upload (stream) with supertest and jest?

我的API中有一个图像上传端点,它接受application/octet-stream请求并处理这些流。 我想为这个端点编写测试覆盖,但无法弄清楚如何使用supertest来传输图像。

到目前为止,这是我的代码:

import request from 'supertest'

const testImage = `${__dirname}/../../../assets/test_image.jpg`

describe('Upload endpoint', () => {

  test('Successfully uploads jpg image', async () =>
    request(app)
      .post(`${ROOT_URL}${endpoints.add_image.route}`)
      .set('Authorization', `Bearer ${process.env.testUserJWT}`)
      .set('content-type', 'application/octet-stream')
      .pipe(fs.createReadStream(testImage))
      .on('finish', (something) => {
        console.log(something)
      }))

})

这个代码什么都不产生,从不调用finish事件,没有控制台记录,并且这个测试套件实际上没有任何预期。 我无法将.expect到此请求,否则我收到此运行时错误:

TypeError:(0,_supertest2.default)(...)。post(...)。set(...)。set(...)。pipe(...)。expect不是函数

这样的事情是如何完成的?

这应该工作。 要将数据传递给请求,您必须告诉可读流管道到请求。 另一种方法是从服务器接收数据。 这也使用done而不是async因为管道不能与async / await一起使用。

同样值得一提的是,默认情况下,管道将调用end ,然后superagent将调用end ,导致关于end被调用两次的错误。 要解决这个问题,你必须告诉管道调用不要这样做,然后在流的on end事件中调用end。

import request from 'supertest'

const testImage = `${__dirname}/../../../assets/test_image.jpg`

describe('Upload endpoint', () => {

  test('Successfully uploads jpg image', (done) => {
      const req = request(app)
          .post(`${ROOT_URL}${endpoints.add_image.route}`)
          .set('Authorization', `Bearer ${process.env.testUserJWT}`)
          .set('content-type', 'application/octet-stream')

      const imgStream = fs.createReadStream(testImage);
      imgStream.on('end', () => req.end(done));
      imgStream.pipe(req, {end: false})
  })
})

编辑添加:这对我来说很小的文件。 如果我尝试使用大型test_image.jpg进行测试,请求会超时。

const testImage = `${__dirname}/../../../assets/test_image.jpg`

describe('Upload endpoint', () => {

  test('Successfully uploads jpg image', async () =>
    request(app)
      .post(`${ROOT_URL}${endpoints.add_image.route}`)
      .set('Authorization', `Bearer ${process.env.testUserJWT}`)
      .attach("name",testImage,{ contentType: 'application/octet-stream' })
      .expect(200)
      .then(response => {
          console.log("response",response);
      })
  );
});

我认为您实际上想要使用fs.createReadStream(testImage)将该图像读入您的请求,因为fs.createWriteStream(testImage)会将数据写入提供的文件描述符(在本例中为testImage )。 您可以随时查看Node Streams,了解它们的工作原理。

我不是在那里你得到相当肯定finish从事件supertest ,但你可以看到如何使用.pipe()方法在这里

您可能还想考虑使用supertest 多部分附件 ,如果这更适合您的测试。

我不得不假设您的上传方法将主体作为输入而不是多部分表单数据。 以下是传递原始主体以进行上传的示例

const request = require('supertest');
const express = require('express');
const fs = require('fs')
const app = express();
var bodyParser = require('body-parser')
app.use(bodyParser.raw({type: 'application/octet-stream'}))

app.post('/user', function(req, res) {
    res.status(200).json({ name: 'tobi' });
});

testImage = './package.json'

resp = request(app)
    .post('/user')

    resp.set('Authorization', `Bearer Test`).set('Content-Type', 'application/octet-stream')

    resp.send(fs.readFileSync(testImage, 'utf-8'))
    resp.expect(200)
    .then(response => {
        console.log("response",response);
    }).catch((err) => {
        console.log(err)
    })

如果您使用multipart/form-data则下面的代码显示了一个示例

const request = require('supertest');
const express = require('express');
const fs = require('fs')
const app = express();

app.post('/user', function(req, res) {
    // capture the encoded form data
    req.on('data', (data) => {
        console.log(data.toString());
    });

    // send a response when finished reading
    // the encoded form data
    req.on('end', () => {
        res.status(200).json({ name: 'tobi' });
    });

});

testImage = './package.json'

resp = request(app)
    .post('/user')

    resp.set('Authorization', `Bearer Test`)
    resp.attach("file", testImage)
    resp.expect(200)
    .then(response => {
        console.log("response",response);
    }).catch((err) => {
        console.log(err)
    })

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM