Typescript 测试驱动开发 TDD (15)

发布时间 2023-09-22 15:43:53作者: 天涯上过客

异步测试 (Asynchronous tests)


正如我们在探索JavaScript和TypeScript时所看到的,我们编写的大部分代码都是异步的。这意味着我们无法准确控制回调函数何时被调用,或者Promise何时解析,因为我们正在等待一个超出我们控制范围的事件发生。这经常在单元测试中引起问题,在这种情况下,我们需要等待异步事件完成后才能继续进行测试。以下是一个示例类:

1 class MockAsync {
2       executeSlowFunction(
3               complete: (value: string) => void
4       ) {
5             setTimeout(() => {
6                  complete(`competed`);
7             },1000);
8       }
9 }

在这里,我们有一个名为MockAsync的类,它有一个名为executeSlowFunction的方法。该方法接受一个名为complete的回调函数作为唯一参数,并在1秒后调用它。我们可以按照以下方式编写对这个类的测试:

 

 1 describe("failing async tests", () => {
 2      it("should wait for callback to complete", () => {
 3           let mockAsync = new MockAsync();
 4           console.log(`1. calling executeSlowFunction`);
 5           let returnValue !: string;
 6           mockAsync.executeSlowFunction((value: string) => {
 7                console.log(`2. complete called`);
 8                returnedValue = value;
 9           });
10 
11      })
12 });

在这里,我们有一个名为"failing async tests"的测试套件,以及一个名为"should wait for callback to complete"的测试。该测试首先创建了一个名为mockAsync的MockAsync类实例。然后它向控制台输出一条消息,并创建了一个变量named returnedValue来保存调用executeSlowFunction方法时返回的值。接下来,它调用executeSlowValueFunction函数并定义了一个回调函数。这个回调函数向控制台输出一条消息,并将回调返回的值存储在returnedValue变量中。然后,该测试向控制台输出第三条消息,并检查returnedValue变量是否包含字符串值"completed"。

运行此测试,然而,会得到以下的失败输出:

在这里,我们可以看到打印到控制台的消息是"1. calling executeSlowFunction"和"3. checking return value"。我们完全没有收到消息"2. executeSlowFunctionReturned"。我们的测试也失败了,因为返回值变量expectedValue应该是 "completed",但实际上是undefined的。

导致这个测试失败的原因是测试本身没有等待1秒钟,以便executeSlowFunction函数调用完成回调。我们真正需要的是一种信号方式,告诉我们的测试只有在异步调用完成后才执行测试期望值。