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

use*_*463 3 unit-testing jasmine angularjs ecmascript-2017

我看过很多关于如何在单元测试中使用 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.
        });
    });
});
Run Code Online (Sandbox Code Playgroud)

运行 angular 1.5 和 jasmine-core 2.6。

sky*_*ize 7

该.then承诺的超负荷处理任何承诺或值,并且await是语法糖调用then。

所以没有理由要求你的间谍返回一个承诺,甚至一个值。返回,即使undefined,应该触发 触发await,并启动您的其余async功能。

我相信你的问题是你没有doSomething在尝试测试它所做的之前等待承诺解决。像这样的事情应该会让你更有把握。

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


小智 0

Jasmine 有异步支持。您也许可以通过这种方式找到解决方案。

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

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

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

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

以你的例子来说,

async doSomething(reqObj) {
    try {
       const val = await this.otherCall(reqObj);
       return this.processResp(val);
    }
}
Run Code Online (Sandbox Code Playgroud)

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

做一些应该被 e2e 测试覆盖的事情。

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