在前端开发中,自动化测试是一个非常重要的环节。Jest 是一个广泛使用的 JavaScript 测试框架,它快速、简单且可以自定义。然而,在写 Jest 测试用例时,有时候会需要进行对象比较。而使用深度匹配在比较某些复杂对象时可能会导致一些问题。本文将介绍如何在 Jest 测试中避免使用深度匹配,同时提供一些示例代码,以帮助你更好地了解。
什么是深度匹配?
深度匹配是比较两个对象(或数组)时,比较它们每一个属性的值。也就是说,如果两个对象或数组的属性完全相同,深度匹配将返回 true。下面是一个示例:
expect({ a: { b: 1 } }).toEqual({ a: { b: 1 } }); // true
在上面的代码中,我们比较了两个对象,每个对象的属性都是相等的。因此,这个比较将返回 true。
深度匹配可能出现的问题
虽然深度匹配可以很好地比较对象,但是在某些情况下,它可能会导致一些问题,例如:
对象包含非 Serializable 值
深度比较将比较对象的所有属性的值,包括可能不可序列化的非简单类型,如函数、 Class Definitions 以及某些 DOM 形式。这些值无法进行序列化,因此无法进行深度匹配。如果有人尝试且对象包含非完全序列化值,则会抛出异常。
对象被与不同 API 的比较
深度比较往往假设树的结构是一致的。但如果我们与第三方 API 比较,它们可能会返回与树结构不同的另一种形式的对象,这使得比较不可能。
比较太复杂的对象
在处理某些复杂情况时,深度比较可以变得相当棘手。这可能导致测试耗时较长,使您的测试套件变得过于臃肿。
考虑到上述各方面问题,有时候我们需要避免使用深度匹配。
如何避免深度匹配
下面是一些避免深度匹配的方法:
使用 toMatchSnapshot
Jest 提供了 toMatchSnapshot 方法,它允许我们在不使用深度比较的情况下测试组件或 API 的输出。也就是说,我们可以记录快照(一份 JSON 文件),然后测试代码的输出是否与快照相同。这样就不需要深度比较,也不需要手动编写期望值,只需将测试结果与快照进行比较。
it("renders correctly", () => { const tree = renderer.create(<TestComponent />).toJSON(); expect(tree).toMatchSnapshot(); });
使用对象属性或数组中的下标
我们可以使用对象或数组的属性或下标,手动比较每个值。这样做通常更明确,更易于理解,除非比较的对象非常大或复杂。
const obj1 = { a: "Hello, world!" }; const obj2 = { a: "Hello, world!" }; expect(obj1.a).toBe(obj2.a); // true
模拟 API 响应
当涉及到与第三方 API 交互时,我们应该模拟 API 的响应,以确保我们的数据格式符合预期。这样,我们就可以使用手动比较每个值的方式进行测试。
-- -------------------- ---- ------- ----- ------------ - - ----- - ----- - ----- ------- ---- --- -- -- -- ------------------------------------------
结论
深度比较通常可以快速方便地写出测试用例,但并不是适用于所有情况,而且会出现一些错误。避免使用深度比较的方法包括手动比较每个属性或使用 toMatchSnapshot 检查快照。在处理较大或更复杂的对象时,使用手动比较每个属性或记录快照已经足够了。
来源:JavaScript中文网 ,转载请注明来源 https://www.javascriptcn.com/post/67720ad16d66e0f9aad3f497