Typescript 测试驱动开发 TDD (9)
匹配器 (Matchers)
1. toBe
Jest 使用所谓的匹配器来将测试中的预期值与接收到的值进行匹配。让我们快速看一下其中一些匹配器,如下所示:
1 it("should match with toBe", () => { 2 expect(1).toBe(2); 3 });
在这里,我们使用toBe匹配器来测试值1是否与值2相同。显然,这个测试将会失败,并显示以下消息:
expect(received).toBe(expected) // Object.is equality Expected: 2 Received: 1
在这里,我们可以看到Jest期望值为2,但实际接收到的是1。有趣的是,这条消息中toBe匹配器使用了Object.is相等性。这意味着以下测试将通过:
1 it("should match with toBe using assignment", () => { 2 let objA = {id: 1}; 3 let objB = objA; 4 expect(objA).toBe(objB); 5 });
在这里,我们正在创建一个名为objA的对象实例,并将其值分配给另一个名为objB的变量。这意味着变量objA和objB都指向内存中的同一个对象。我们可以尝试使用toBe匹配器来比较两个不同的对象,如下所示:
1 it("should match with toBe", () => { 2 let objA = {id: 1}; 3 let objB = {id: 1}; 4 expect(objA).toBe(objB); 5 });
在这里,objA和objB具有相同的结构,并且它们具有相同的值,但它们不是内存中的同一个对象。这个测试将产生以下测试失败:
expect(received).toBe(expected) //Object.is equality If it should pass with deep equality, replace "toBe" with "toStrictEqual" Expected: {"id": 1} Received: serializes to the same string
2. toEqual
在这里,我们可以看到我们的测试失败了,因为objA和objB是两个不同的对象。Jest的错误输出也建议我们将toBe替换为toStrictEqual。然而,我们可以使用toEqual匹配器来达到相同的结果,如下所示:
1 it("should match with toEquala", () => { 2 let objA = {id: 1}; 3 let objB = {id: 1}; 4 expect(objA).toEqual(objB); 5 });
在这里,我们的测试通过了,因为toEqual匹配器会正确地将两个对象的形状和值解释为相等。
3. toContain和 toContainEqual
Jest还提供了许多变体的toContain匹配器,用于测试一个值是否包含在另一个值中,如下所示:
1 it("should contain a value", () => { 2 expect("abcde").toContain("cde"); 3 });
在这里,我们的测试期望值 "abcde" 包含值 "cde"。我们也可以将这个概念应用到数组上,如下所示:
1 it("should contain an array item", () => { 2 let objArray = [ 3 {id: 1}, 4 {id: 2} 5 ]; 6 7 expect(objArray).toContainEqual({id: 2}) ; 8 });
在这里,我们有一个名为objArray的对象数组,并且我们的测试期望objArray数组应该包含值{id: 2}。请注意,在这种情况下,我们使用了toContainEqual匹配器,用于检查数组是否包含特定项。
4. not
请注意,使用not属性可以对任何期望进行反转,如下所示:
1 it("should not contain a value", () => { 2 expect("abcde").not.toContain("123"); 3 });
在这里,我们期望值 "abcde" 不包含值 "123"。
Jest的所有匹配器都可以使用not属性作为前缀,以测试不相等性。
5. toThowError
匹配器还具有在抛出错误时进行测试的能力。考虑以下函数:
1 function throwError() { 2 throw new Error("this is an error"); 3 }
在这里,我们有一个名为throwsError的函数,它会抛出一条带有消息"this is an error"的错误。我们可以编写一个测试来验证是否会抛出该错误,如下所示:
1 it("should throw an error", () => { 2 expect( 3 () => {throwError() } 4 ).toThrowError(new Error("this is an error")); 5 });
在这里,我们有一个使用名为 toThrowError 的匹配器的测试,用于测试函数 throwsError 是否确实抛出了错误,并且错误消息是正确的。
请注意,在 expect 中我们提供了一个调用 throwsError 函数的匿名函数。当测试是否会抛出错误时,我们必须将调用抛出错误的函数包装在一个匿名函数中,否则测试本身将无法正确执行。