Typescript 测试驱动开发 TDD (17)
使用async await
如果一个异步函数正在使用Promises,那么我们可以使用async await语法来运行测试,就像我们通常做的一样。例如,考虑以下类,它使用Promise返回一个值,如下所示:
1 class AsyncWithPromise { 2 delayedPromise(): Promise<string> { 3 return new Promise<string>( 4 (resolve: (str: string) => void, 5 reject: (str: string) => void ) => { 6 setTimeout(() => { 7 console.log(`2. returning success`); 8 resolve("success"); 9 }, 1000); 10 } 11 ); 12 } 13 }
在这里,我们有一个名为AsyncWithPromise的类,它有一个名为delayedPromise的方法,该方法返回一个类型为字符串的Promise。这个promise将在控制台上记录一条消息,并在1秒延迟后调用resolve函数并传递字符串值"success"。现在我们可以编写如下的单元测试:
1 describe("async test", () => { 2 it("should wait 1 second for promise to resolve", 3 async () => { 4 let asyncWithPromise = new AsyncWithPromise(); 5 console.log(`1. calling delayedPromise`); 6 let returnValue = await asyncWithPromise.delayedPromise(); 7 console.log(`3. after await`); 8 expect(returnValue).toEqual("success"); 9 }) 10 });
这里,我们有一个名为“async test”(异步测试)的测试套件,其中包含一个名为“should wait 1 second for promise to resolve”(应该等待1秒钟以解决承诺)的单个测试。请注意我们的测试函数前缀带有async关键字。
在这个测试的主体中,我们创建了一个 AsyncWithPromise 类的实例,命名为 asyncWithPromise。然后我们向控制台记录一条消息,并将变量 returnValue 的值设置为调用 delayedPromise 方法的结果。请注意,我们使用 await 关键字来暂停测试执行,直到此 Promise 被解析。然后我们的测试向控制台记录第三条消息,并最终检查 returnValue 变量与预期字符串 "success" 的值是否相等。此测试的输出如下:
在这里,我们可以看到测试通过了,并且测试的执行时间为1,012毫秒。这意味着测试等待Promise被解决了1,000毫秒,而剩下的测试执行时间为12毫秒。还要注意,打印到控制台的消息也是按照正确的顺序。第一条消息是在我们调用delayedPromise函数之前记录的,第二条消息是在延迟1,000毫秒后,在delayedPromise函数内部记录的,第三条消息是在我们的await调用之后记录的。
在单元测试中使用async await语法与在正常代码中使用它完全相同。只要我们用async关键字标记测试函数,当遇到await关键字时,测试将暂停,并在异步代码完成后继续执行。