1

我目前正在为后端进行一些测试,并且我一直在磕磕绊绊,特别是一项测试有时会运行,有时却不会。如果某些特定标头不存在,则错误发生在我的警卫拒绝请求中。所以在我的测试中,应用程序看起来类似于这个

beforeEach(() => {
    app = express();
    const router = express.Router();
    router.post('/media/upload',      
      addSpies,
      PostMediaGuard(sinon.stub().resolves(true)),
      multer(getMulterOptions()).fields([{ name: 'File', maxCount: 1 }]),
      upload
    ); 

    app.use('/', router);
  });

现在添加间谍只会将间谍添加到我的 req、res 和 next 中,然后继续。该错误发生在我的 PostMediaGuard 中。在这里,我将检查存在的标题,如果不存在则拒绝

PostMediaGuard

if(typeof(req.headers['x-some-header']) !== 'string')
      return res.status(400).end('No valid RealmId in Header. Please set X-RealmId');

    if(!await _userMayUploadMediaFile(
      req.headers['x-some-header'],
      req.headers.authorization as string,
      req.user
    ))
      return res.status(403).end(`Not allowed to upload media`);

next();

现在对于我的测试,我将使用 supertest 向我的应用程序发出请求。请求看起来像这样

测试

await request(app)      
        .post('/media/upload')      
        .attach('File', path.join(__dirname, '../../test/media/dummy.jpg'));   

现在,如果我调试一切正常,我将点击该行将状态设置为 400 并在 PostMediaGuard 中结束请求。有时在那之后测试会被断言很好,有时我会得到 ECONABORTED 与以下堆栈

堆栈:“错误: 在 Socket._writeGeneric (net.js:770:11)在 Socket._write 的 writeGeneric (internal/stream_base_commons.js:141:3)的
afterWriteDispatched (internal/stream_base_commons.js:150:25)处写入 ECONNABORTED (net.js:782:8) 在 doWrite (_stream_writable.js:431:12) 在 writeOrBuffer (_stream_writable.js:415:5) 在 Socket.Writable.write (_stream_writable.js:305:11) 在 ClientRequest._writeRaw (_http_outgoing.js:295:17) 在 ClientRequest._send (_http_outgoing.js:271:15) 在 ClientRequest.end (_http_outgoing.js:732:10) 在 Transform.onend (_stream_readable.js:691:10) 在 Object .onceWrapper (events.js:299:28)











在 Transform.emit (events.js:210:5)
在 endReadableNT (_stream_readable.js:1183:12)
在 processTicksAndRejections (internal/process/task_queues.js:80:21)"

现在我假设由于请求的表单数据中发送的文件在后台进行了一些流式传输,并且我试图在完成之前结束请求。但是,我还没有开始任何事情来处理数据,例如创建读取流或尝试将其存储在数据库中。(因为要注意的是,如果所需的标头不存在,我不会这样做)。到目前为止,我发现的几乎所有关于该主题的答案都是由于一些异步流方法开始并试图在请求完成之前结束请求。但是由于那时我还没有开始那些我不知道我错在哪里

任何想法可能是什么问题?

4

1 回答 1

2

现在这似乎是 supertest 的一个问题(GitHub 上的问题)

但是,至少有一种解决方法可以通过将连接设置为在标头中保持活动状态来使其工作。

如果您查看我的示例以获取问题中的请求,请将其更改为类似这样

await request(app)      
        .post('/media/upload')      
        .attach('File', path.join(__dirname, '../../test/media/dummy.jpg'))
        .set('Connection', 'keep-alive'); 

现在我仍然无法理解超测会发生什么。这个问题指出,在表单数据请求中,可能会调用双重回调,因此它可能与此相关。

截至目前,我不了解根本原因,但我会在发现后立即在此处更新。至少现在有一种解决方法可以让它工作。

于 2020-04-08T13:00:14.130 回答