简体   繁体   English

Jest/SuperTest 如何在一组承诺中正确预期 Socket Hangup?

[英]Jest/SuperTest how to correctly expect Socket Hangup across a set of promises?

I have a test that says "After approx X concurrent connections, I should see socket hangups since my service will stop answering someone hammering me."我有一个测试,上面写着“在大约 X 个并发连接之后,我应该看到套接字挂断,因为我的服务将停止回答有人锤我。”

This works pretty well after a lot of painful trial and error, but because I am using await Promise.all(myrequests) the first time I see a hangup it throws a socket hang up exception.经过大量痛苦的试验和错误后,这工作得很好,但是因为我第一次看到挂断时使用的是await Promise.all(myrequests) ,它会引发socket hang up异常。

This works, but causes some error messages, since my routine for hanging up does some debug logging, and the test is over at this point.这可行,但会导致一些错误消息,因为我的挂机例程会进行一些调试日志记录,此时测试已经结束。

What's the best way to say: "wait for all of these, even when they throw errors?"最好的说法是:“等待所有这些,即使它们抛出错误?”

My jest/supertest problem block looks something like:我的笑话/超级测试问题块看起来像:

 //Send enough concurrent connections to trip the dropout
 for(var i = 0;MAX_CONCURRENT_CONNECTIONS+5;i++) 
    {
       requests.push(request(app).get('/'))   
    }
    //wait for all the connections to resolve    
    const t = async () => {          
       await Promise.all(requests);                    
    };
    //and make sure some drop off
    expect(t).toThrow("socket hang up"); //this also doesn't match the error string right but that is because I'm not as experienced in this sort of thing as I'd like!

    //however after this, the test ends, and my back end logging causes problems since the test is over!

What's the best way to still wait for all promises in requests even when one throws on await Promise.all(requests) ?即使抛出await Promise.all(requests) ,仍然等待请求中所有承诺的最佳方法是什么?

I can do the following ugly bit of code, but I'm looking for the right way to write this:)我可以做以下丑陋的代码,但我正在寻找正确的方法来写这个:)

        let gotConnReset = false
        try
        {
           await Promise.all(requests);                                    
        }
        catch(err)
        {
            if(err.message == "socket hang up")
            {
                gotConnReset = true;
            }            
        }
        assert(gotConnReset === true);
        //wait for all the other requests so that Jest doesn't yell at us!
        await Promise.allSettled(requests); 

I don't know that Jest has something to help but there's Promise.allSettled which will wait for all promises to fulfill or reject, returning an array of all results.我不知道 Jest 有什么可以帮助的,但有Promise.allSettled将等待所有承诺履行或拒绝,返回所有结果的数组。 The rejected promises will have a .reason attached.被拒绝的承诺将附加一个.reason

The main difference is that Jest will be matching error objects rather than using the thrown error matchers so some of the error specific functionality is not there.主要区别在于 Jest 将匹配错误对象而不是使用抛出的错误匹配器,因此某些特定于错误的功能不存在。

test('allSettled rejects', async () => {
  class Wat extends Error {}
  const resError = new Wat('Nope')
  resError.code = 'NO'
  const res = await Promise.allSettled([
    Promise.resolve(1),
    Promise.reject(resError),
    Promise.resolve(3),
  ])
  expect(res).toEqual(
    expect.arrayContaining([
      { status: 'rejected', reason: new Error('Nope') },
    ])
  )
})
  ✓ allSettled rejects (2 ms)

If you want to avoid the "loose" matching of the example above which passes with any Error object if the message matches, it might need something like jest-matcher-specific-error or to expect.extend an error matcher如果您想避免上面示例的“松散”匹配,如果message匹配,则通过任何Error object,它可能需要类似jest-matcher-specific-errorexpect.extend错误匹配器

The results can use filter / map or reduce to test rejections directly.结果可以使用filter / map或直接reduce到测试拒绝。

(await Promise.allSettled())
  .filter(o => o.status === 'rejected')
  .map(o => o.reason)`

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

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