【问题标题】:How to test a method that uses async/await?如何测试使用 async/await 的方法?
【发布时间】:2018-06-29 00:40:53
【问题描述】:

我看过很多关于如何在单元测试中使用 async/await 的文章,但我的需求正好相反。

如何为使用 async/await 的方法编写测试?

我的规范无法在“等待”行之后访问任何代码。具体来说,规范在两个方面失败。

1) HelloWorld.otherCall 返回 undefined 而不是我指定的返回值

2) HelloWorld.processResp 永远不会被调用

class HelloWorld {

    async doSomething(reqObj) {
        try {
           const val = await this.otherCall(reqObj);
           console.warn(val); // undefined
           return this.processResp(val);
        }
    }

}

describe('HelloWorld test', function () {

    let sut = new HelloWorld(); //gross simplification for demo purposes

    describe('doSomething()', function () {
        beforeEach(function mockInputs() {
           this.resp = 'plz help - S.O.S.';
        });

        beforeEach(function createSpy() {
            spyOn(sut, 'otherCall').and.returnValue( $q.resolve(this.resp) );
            spyOn(sut, 'processResp');
        });

        it('should call otherCall() with proper arguments', function () {
            //this test passes   
        });

        it('should call processResp() with proper arguments', function () {
           sut.doSomething({});
           $rootScope.$apply(); //you need this to execute a promise chain..

           expect(sut.processResp).toHaveBeenCalledWith(this.resp); 
           //Expected spy processResp to have been called with [ 'plz help SOS' ] but it was never called.
        });
    });
});

运行 angular 1.5 和 jasmine-core 2.6。

【问题讨论】:

    标签: angularjs unit-testing jasmine ecmascript-2017


    【解决方案1】:

    promise 的.then 被重载以处理promise 或值,await 是调用then 的语法糖。

    所以没有理由要求你的间谍返回一个承诺,甚至是一个值。完全返回,即使undefined,应该触发await 触发,并启动你的async 函数的其余部分。

    我相信您的问题是您没有等待doSomething 承诺解决,然后再尝试测试它的作用。这样的事情应该会让你更了解情况。

    it('should call processResp() with proper arguments', async function () {
       await sut.doSomething({});
       // ...
    });
    

    【讨论】:

      【解决方案2】:

      茉莉花有Asynchronous Support。您可能可以通过这种方式找到解决方案。

      就个人而言,我认为您根本不应该测试这些方法。

      测试状态表示我们正在验证被测代码是否返回正确的结果。

      测试交互意味着我们正在验证被测代码是否正确调用了某些方法。

      在大多数情况下,测试状态更好。

      在你的例子中,

      async doSomething(reqObj) {
          try {
             const val = await this.otherCall(reqObj);
             return this.processResp(val);
          }
      }
      

      只要 otherCall 和 processResp 被单元测试很好地覆盖你就好了。

      做某事应该包含在 e2e 测试中。

      您可以在http://spectory.com/blog/Test%20Doubles%20For%20Dummies阅读更多相关信息

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2022-06-23
        • 1970-01-01
        • 2019-08-12
        • 2019-01-17
        • 1970-01-01
        • 2018-05-27
        • 2018-01-06
        相关资源
        最近更新 更多