Javascript 如何使用supertest和jest测试图像上传(流)?
我的API中有一个图像上载端点,它接受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
应用程序/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,我想这应该可以,你能检查并更新吗?