我正在尝试测试应用程序不同部分引发的错误。该应用程序通过加密将来自请求(分段文件上传)的流传输到 S3 存储桶。
我能够在
_read
中为加密流创建模拟异常,但对于目标可写流,如果我尝试使用 _write
相同的方法,我会得到一个未处理的异常。
以下测试有效,但如果我切换到使用
_write
,则错误未被正确捕获
it('error in encryption stream', async () => {
const encryptionStream = new DuplexMock();
encryptionStream._read = () => {
throw new Error('Test Exception')
};
const writeStream = new BufferWritableMock();
CryptoService.encryptionStream.mockImplementation(()=> encryptionStream);
S3Service.uploadFromStream.mockImplementation(() => writeStream);
const result = await supertest(appInstance)
.post(`${storePath}?skip-encryption=false`)
.attach('file', filePath);
expect(result.statusCode).toBe(500);
});
也许我的处理方式是错误的......?
在我疯狂地尝试让它工作时,我将 cryptoStream 更新为 DuplexMock 这应该是 PassThrough ,数据
writeStream
没有被原始问题中的代码调用(我现在已经更新了上面的代码)
我添加了下面不起作用的测试..
it('error in S3 stream', async () => {
const encryptionStream = new PassThrough();
const writeStream = new ObjectWritableMock();
writeStream._write = (chunk, enc, next) => {
new Error('Test Exception');
};
CryptoService.encryptionStream.mockImplementation(()=> encryptionStream);
S3Service.uploadFromStream.mockImplementation(() => writeStream);
const result = await supertest(appInstance)
.post(`${storePath}?skip-encryption=false`)
.attach('file', filePath)
expect(result.statusCode).toBe(500);
}, 10*1000
);
在努力解决这个问题一段时间后,我发现了代码的三个问题......
在模拟流中引发错误时,我需要调用
next
,使用_read
时没有下一个参数,但使用_write
我认为应该是:
writeStream._write = (chunk, enc, next) => {
next(new Error('Test Exception')); //<-- Don't throw but pass to 'next'
};
SUPERTEST
和 read ECONNRESET
当尝试在我的 Windows 笔记本电脑上创建该问题的最小存储库时,我遇到了更多问题。使用 supertest 我的测试失败了,并出现
read ECONNRESET
,经过相当大的努力后,我意识到这些问题中至少有一个是 Windows 特有的!有了这些知识,我发现了这个问题,这有助于确定另外两个问题:
read ECONNRESET
(问题二)在 Windows 上,我注意到每个返回错误的测试都会失败,并将
read ECONNRESET
写入控制台:
为了在 Windows 上修复此问题,我们只需要在使用 supertest 执行请求时包含
connection: 'keep-alive'
标头即可。像这样:
const result = await supertest(appInstance)
.post("/v1/store")
.query({ "skip-encryption": "true" })
.set('connection', 'keep-alive') //<-- this is important
.attach('file', filePath)
read ECONNRESET
(第三期)最后一个问题是我自己没有阅读手册的错。先前链接的问题还提到格式不正确的路径可能会导致问题,您可以在上面的代码中看到,我在路径中包含查询 pram,正确包含查询字符串(见下文)是让我的测试正常工作的最后一步.
const result = await supertest(appInstance)
.post("/v1/store")
.query({ "skip-encryption": "true" }) // <-- add query string
.set('connection', 'keep-alive')
.attach('file', filePath)