Python中如何正确Mock Firestore的链式where查询方法?
问题原因
- Firestore的
where是链式API,每一次调用where都会返回一个新的查询实例,后续的where方法是在这个新返回的实例上触发,而非原始的MY_COLLECTION_GROUP对象 - 你只Mock了顶层的
MY_COLLECTION_GROUP.where方法,没有处理后续链式调用的实例方法,所以实际调用链路和你预期的不符
解决方法
方案1:让Mock对象返回自身(更简洁,推荐)
只需要给Mock的where方法设置返回值为自身,这样每次调用where之后返回的都是同一个Mock实例,所有的where调用都会记录在这个实例上,直接用你原来的断言逻辑即可。如果后续还有get()、stream()等其他链式调用,同样可以在这个Mock实例上设置对应的返回值来模拟查询结果,不需要额外Mock其他对象。
修改后的测试代码如下:
from mock import call, patch @patch("mymodule.MY_COLLECTION_GROUP.where") def test_function_to_test(mocked_where_function): # 关键设置:让where调用后返回自身,承接后续链式调用 mocked_where_function.return_value = mocked_where_function # 调用待测试函数 test_data = { "dateTime": "2021, 09, 15", "user_id": "12", "valid_age": 18 } function_to_test(test_data) # 直接按原始逻辑断言即可 mocked_where_function.assert_has_calls([ call("eventDateTime", "==", test_data["dateTime"]), call("user.id", "==", test_data["user_id"]), call("user.age", ">=", test_data["valid_age"]), ])
方案2:匹配实际调用链路
如果不想修改Mock的返回逻辑,也可以按照实际产生的调用链来写断言,和报错提示里的实际调用格式对齐即可:
mocked_where_function.assert_has_calls([ call("eventDateTime", "==", test_data["dateTime"]), call().where("user.id", "==", test_data["user_id"]), call().where().where("user.age", ">=", test_data["valid_age"]), ])
这种方案的缺点是链式调用越长,断言写法越冗余,更推荐使用方案1。
内容的提问来源于stack exchange,提问作者Keshav Bhatiya
相关产品推荐
相关产品推荐

