【问题标题】:How to test a asynchronous server code using mocha chai?如何使用 mocha chai 测试异步服务器代码?
【发布时间】:2018-03-09 12:03:23
【问题描述】:

在我的 mocha-test 套件中,我想测试一个在后台进行异步调用的功能。如何等到异步调用完成?

例如,我打了两个背靠背的电话。第一个 post 调用也在内部进行异步调用,直到异步操作完成,第二个 post 调用不会通过。

我需要以下任何一种:

1) 在两个 post 调用之间设置一个延迟,以确保第一个 post 中的异步部分是完整的。
2) 重复进行第二次 post call 直到它通过。
3) 或者如何通过 mocha-chai 测试异步调用?

下面是例子:

describe('Back to back post calls with asynchronous operation', ()=> {

            it('1st and 2nd post', (done) => {
                chai.request(server)
                .post('/thisis/1st_post')
                .send()
                .end((err, res) => {
                 expect(res.statusCode).to.equal(200);

                 /* HERE I Need A Delay or a way to call                   
               the below post call may be for 5 times */                       

                 chai.request(server)
                .post('/thisis/second_post')
                .send()
                .end((err, res) => {
                 expect(res.statusCode).to.equal(200);


                });

                done();
                });
            });         

        });

有没有办法解决这个问题?请帮忙。

谢谢。

【问题讨论】:

    标签: node.js mocha.js asynchronous-javascript


    【解决方案1】:

    为了使用 mocha 测试异步函数,您有以下可能性

    仅在序列中的最后一个回调执行后使用done

    it('1st and 2nd post', (done) => {
      chai.request(server)
        .post('/thisis/1st_post')
        .send()
        .end((err, res) => {
          expect(res.statusCode).to.equal(200);
    
          /* HERE I Need A Delay or a way to call
        the below post call may be for 5 times */
    
          chai.request(server)
            .post('/thisis/second_post')
            .send()
            .end((err, res) => {
              expect(res.statusCode).to.equal(200);
    
              //call done only after the last callback was executed
              done();
            });
        });
    });
    

    使用带有承诺的done回调

    describe('test', () => {
      it('should do something async', (done) => {
        firstAsyncCall
           .then(() => {
              secondAsyncCall()
                .then(() => {
                  done() // call done when you finished your calls
                }
           })
      });
    })
    

    经过适当的重构,你会得到类似的东西

    describe('test', () => {
      it('should do something async', (done) => {
        firstAsyncCall()
          .then(secondAsyncCall())
          .then(() => {
            // do your assertions
            done()
          })
          .catch(done)
      })
    })
    

    使用async await,更干净

    describe('test', () => {
      it('should do something async', async () => {
        const first = await firstAsyncCall()
        const second = await secondAsyncCall()
    
        // do your assertion, no done needed
      });
    })
    

    另一个需要记住的时刻是运行 mocha 测试时的 --timeout 参数。默认 mocha 等待2000 毫秒,当服务器响应较慢时,您应该指定更大的数量。

    mocha --timeout 10000

    【讨论】:

    • 我没有像 firstAsyncCall() 和 secondAsyncCall() 这样的函数。我只需要通过路线打两个电话。正如我所说,第一个 post 调用完成并返回到 callback ,但是在后台发生了一些其他异步调用。因此,当第二个 post 调用发生在第一个 post 调用的回调中时,后面运行的 async 函数还没有完成。所以我只需要在第二篇文章开始之前休息/时间延迟。可能是我希望在我将其断言为通过/失败之前发生 3-4 次第二次通话。
    • 您还可以假设在我展示的两个 post 调用之前和之后还有一些 post/get/pull 调用链。只有这两个 post call 之间需要有时间延迟。
    • 能否请您说明我是否可以将第二个 post 调用放入一个函数中并继续循环调用该函数,直到获得所需的结果?不知道这个异步等待是如何工作的。
    • 任何关于如何测试异步端点的问题的帮助将不胜感激。
    • 能否请您添加您添加的测试代码,这样会更容易帮助您。
    猜你喜欢
    • 2020-02-28
    • 2015-06-02
    • 2018-03-06
    • 2017-06-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-06-20
    相关资源
    最近更新 更多