如何使用Jest测试Express应用程序,当您遇到异步超时错误时?

huangapple go评论91阅读模式
英文:

How to test express app with jest when you get an async timeout error?

问题

我正在测试以下端点:

app.post('/api/master/makeLeaderInZone', authenticateMaster, (request, response) => {
    var body = _.pick(request.body, ['zoneId', 'leaderId'])
    
    Zone.findById(body.zoneId).then((zone) => {
        if (zone) {
            return zone.addLeader(body.leaderId)
        } else {
            return Promise.reject()
        }
    }).then(() => {
        return Volunteer.findById(body.leaderId)
    }).then((volunteer) => {
        if (volunteer) {
            return volunteer.addToZoneAsLeader(body.zoneId)
        } else {
            return Promise.reject()
        }
    }).then(() => {
        response.status(200).send()
    }).catch((error) => {
        response.status(400).send()
    })
})

这是我正在使用的测试:

describe('makeLeaderInZone', () => {
    test('neither zone nor volunteer valid',  () => {
         request(app)
        .post('/api/master/makeLeaderInZone')
        .set('master-auth', 'master')
        .send().expect(400)
    })
})

当我在 Postman 中测试时,这个端点运行得非常完美。然而,使用这个测试,我得到了以下错误:

Timeout - Async callback was not invoked within the 5000ms timeout specified by jest.setTimeout.Error: Timeout - Async callback was not invoked within the 5000ms timeout specified by jest.setTimeout.

如同在这个答案中提到的,我在测试中添加了以下代码行,以使 jest 等待更长时间来完成我的请求:

jest.setTimeout(30000);

但是,我仍然得到了完全相同的错误。就好像 jest 忽略了这一行,只等待了 5000 毫秒。

我应该怎么做才能使这个测试工作?

英文:

I'm testing the following endpoint:

app.post('/api/master/makeLeaderInZone', authenticateMaster, (request, response) => {
    var body = _.pick(request.body, ['zoneId', 'leaderId'])
    
    Zone.findById(body.zoneId).then((zone) => {
        if (zone) {
            return zone.addLeader(body.leaderId)
        } else {
            return Promise.reject()
        }
    }).then(() => {
        return Volunteer.findById(body.leaderId)
    }).then((volunteer) => {
        if (volunteer) {
            return volunteer.addToZoneAsLeader(body.zoneId)
        } else {
            return Promise.reject()
        }
    }).then(() => {
        response.status(200).send()
    }).catch((error) => {
        response.status(400).send()
    })
})

And this is the test I am using:

describe('makeLeaderInZone', () => {
    test('neither zone nor volunteer valid',  () => {
         request(app)
        .post('/api/master/makeLeaderInZone')
        .set('master-auth', 'master')
        .send().expect(400)
    })
})

This endpoint worked perfectly when I tested it using postman. However, with this test, I got the following error:

> Timeout - Async callback was not invoked within the 5000ms timeout
> specified by jest.setTimeout.Error: Timeout - Async callback was not
> invoked within the 5000ms timeout specified by jest.setTimeout.

As mentioned in this answer, I added the following line of code inside my test to make jest wait longer for my request to complete:

jest.setTimeout(30000);

But, I still got the exact same error. It's as if jest ignores this line and only waits for 5000ms.

What should I do to make this test work?

答案1

得分: 1

只是确认一下,你是否像这里提到的那样将 setTimeout 选项添加到你的 jest.setup.js 文件中?

https://jestjs.io/docs/en/configuration#setupfilesafterenv-array

为了在每个测试中进行设置,你需要将它设置为测试的第三个参数。

test('example', async () => {
  await new Promise(resolve => setTimeout(resolve, 1000));
}, 500);

所以在你的情况下,应该是这样的:

describe('makeLeaderInZone', () => {
    test('neither zone nor volunteer valid',  () => {
         request(app)
        .post('/api/master/makeLeaderInZone')
        .set('master-auth', 'master')
        .send().expect(400)
    }, 30000)
})
英文:

Just to confirm, did you add the setTimeout option to your jest.setup.js file as referenced here?

https://jestjs.io/docs/en/configuration#setupfilesafterenv-array

in order to set it on a test by test basis, you need to set it as a third argument to your test.

test('example', async () => {
  await new Promise(resolve => setTimeout(resolve, 1000));
}, 500);

So in your instance, it would be

describe('makeLeaderInZone', () => {
    test('neither zone nor volunteer valid',  () => {
         request(app)
        .post('/api/master/makeLeaderInZone')
        .set('master-auth', 'master')
        .send().expect(400)
    }, 30000)
})

</details>



# 答案2
**得分**: 1

我终于弄清楚了。不知道为什么,但出于某种原因,如果我将以下代码行放在测试函数内部:

jest.setTimeout(30000);

Jest 就会忽略它并使用默认的超时值 5000 毫秒。但是,如果我将这行代码放在描述块内但测试本身之外,就像这样:

describe('makeLeaderInZone', () => {
jest.setTimeout(10000)

test('neither zone nor volunteer valid', async () => {
    await request(app)
    .post('/api/master/makeLeaderInZone')
    .set('master-auth', 'master')
    .send().expect(400)
})

})

它会完美地工作,并等待我的请求完成(大约需要 8.5 秒)。

<details>
<summary>英文:</summary>

I finally figured it out. I don&#39;t know why but for some reason, if I put the following line of code:

jest.setTimeout(30000);

inside the test function itself, jest just ignores it and uses the default timeout values of 5000 ms. But if I put this line inside the describe block but outside the test itself, like this:

describe('makeLeaderInZone', () => {
jest.setTimeout(10000)

test(&#39;neither zone nor volunteer valid&#39;, async () =&gt; {
    await request(app)
    .post(&#39;/api/master/makeLeaderInZone&#39;)
    .set(&#39;master-auth&#39;, &#39;master&#39;)
    .send().expect(400)
})

})

it works perfectly and waits for my request to complete (which takes roughly 8.5 seconds).

</details>



huangapple
  • 本文由 发表于 2020年1月3日 19:34:07
  • 转载请务必保留本文链接:https://go.coder-hub.com/59577911.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定