如何测试Jest中resolves返回对象的属性值?
解决Promise返回对象属性的测试问题
我猜你是在Jest这类测试框架里写异步测试时踩了语法坑!问题出在对.resolves修饰符的用法理解上——它不是让你直接访问Promise结果的属性,而是需要搭配Jest的匹配器来使用,直接点属性自然会报错说它没有then方法。
先说说你哪里错了
当你尝试写expect(myMethod()).resolves.email.toBe('an@email')时,.resolves并不是返回Promise resolve后的实际对象,它是Jest提供的一个特殊匹配器包装器,用来标记你要断言的是Promise最终resolve的值。所以你不能像操作普通JS对象那样直接访问它的email属性,这就导致了“resolves不是Promise”的错误。
正确的两种写法
方法1:用async/await(推荐,更直观)
这种方式先等待Promise完成,拿到实际的结果对象后再断言属性,代码可读性拉满:
test('返回对象包含正确的email', async () => { const result = await myMethod(); // 等待Promise resolve拿到结果 expect(result.email).toBe('an@email'); // 直接断言属性值 });
注意要给测试函数加上async关键字,这样才能用await。
方法2:用.resolves搭配匹配器
如果你偏爱链式写法,可以用.resolves加上Jest的匹配器来断言属性,比如toMatchObject或者toHaveProperty:
test('返回对象包含正确的email', () => { // 匹配对象的部分属性 expect(myMethod()).resolves.toMatchObject({ email: 'an@email' }); // 直接断言指定属性的值 expect(myMethod()).resolves.toHaveProperty('email', 'an@email'); });
这里.resolves后面必须跟Jest的匹配器,不能直接访问属性,这样框架才能正确处理异步断言。
小提醒
如果你用的是其他测试框架(比如Mocha+Chai),思路类似:要么用async/await拿到结果再断言,要么用框架提供的异步匹配器(比如Chai的eventually)来链式断言属性,本质都是不能直接跳过匹配器去访问包装后的Promise结果。
内容的提问来源于stack exchange,提问作者Eduardo Yáñez Parareda
相关产品推荐
相关产品推荐

