Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/arrays/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 如何使用supertest和jest测试图像上传(流)?_Javascript_Streaming_Jestjs_Supertest_Superagent - Fatal编程技术网

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

Javascript 如何使用supertest和jest测试图像上传(流)?,javascript,streaming,jestjs,supertest,superagent,Javascript,Streaming,Jestjs,Supertest,Superagent,我的API中有一个图像上载端点,它接受应用程序/octet流请求并处理这些流。我想为此端点编写测试覆盖率,但无法确定如何使用supertest来流式传输图像 以下是我目前的代码: import request from 'supertest' const testImage = `${__dirname}/../../../assets/test_image.jpg` describe('Upload endpoint', () => { test('Successfully u

我的API中有一个图像上载端点,它接受
应用程序/octet流
请求并处理这些流。我想为此端点编写测试覆盖率,但无法确定如何使用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不是函数


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

我认为您实际上希望使用
fs.createReadStream(testImage)
将该图像读取到您的请求中,因为
fs.createWriteStream(testImage)
将数据写入提供的文件描述符中(在本例中为
testImage

我不太确定您从哪里获得
supertest
finish
事件,但是您可以看到如何使用
.pipe()
方法


您可能还想考虑使用<代码>超测试< /C>,如果这更适合您的测试。 这应该行得通。要通过管道将数据传输到请求,您必须告诉可读流通过管道传输到请求。另一种方法是从服务器接收数据。这也使用了

done
而不是
async
,因为管道不使用async/await

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);
      })
  );
});
同样没有价值的是,默认情况下管道将调用
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 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)
    })
如果使用
多部分/表单数据
,下面的代码将显示一个示例

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

对不起,那只是我的错别字。当然,我们正在读取流。要将数据传输到请求,您必须告诉可读的流将数据传输到请求。e、 g.
imageStream.pipe(req)
async/
wait
仅适用于承诺,而不适用于流。您需要将测试函数更改为使用
(done)
,并在管道的
finish
/
close
事件中调用
done()
。@popthestack如果您写出一个完整的工作答案,我很乐意给您奖金。@isachman,这里的请求对象是什么?如果可能,提供最低限度的git回购,您应该得到修复soon@TarunLalwani很抱歉,
request
是问题标题中指出的
supertest
库。我认为您不应该同时使用
expect
then
。无论如何,在运行代码时(这与我已经尝试过的非常类似),我得到的错误是标题内容类型不是
application/octet-stream
。似乎
attach
方法重写了标题。是的,我忘了删除内容类型。我更新了answer@IsaacHinman,我想这应该可以,你能检查并更新吗?