我想对一些mongo查询进行模拟测试,但是当我尝试在同一范围内模拟两个不同的mongo对象(光标和集合(时,我遇到了问题。我不能把原始代码放在这里,但我做了一个有同样问题的泛型。
这是我想要测试的函数(使用查找和区分(:
def get_some_info(date1, date2):
data = collection.find({"timestamp": {"$lt": date1, "$gt": date2})
id_list = data.distinct("id")
for id in id_list :
collection.find({"id" : id})
这是测试代码:
@mock.patch.object(Collection, "find")
@mock.patch.object(Cursor, "distinct")
def test_get_some_info(self, mock_distinct, mock_find):
date1 = datetime.datetime()
date2 = datetime.datetime()
mock_distinct.return_value = ["id1", "id2"]
find_parameters1 = {"timestamp": {"$lt": date1, "$gt": date2}
find_parameters2 = {"id" : "id1"}
self.my_class.get_some_info(date1, date2)
mock_find.assert_called_with(find_parameters1)
mock_find.assert_any_call(find_parameters2)
当我运行测试时,我收到以下错误消息:
'%s 调用未找到' % expected_string 断言错误: find({"id" : "id1"}( 未找到调用
所以我打印了id_list的值:
def get_some_info(date1, date2):
data = collection.find({"timestamp": {"$lt": date1, "$gt": date2})
id_list = data.distinct("id")
print id_list
for id in id_list :
collection.find({"id" : id})
这是id_list的值:
MagicMock name='find((.distinct((' id='139719585597776'
但预期是:["id1"、"id2"]
当我评论光标的模拟时,id_list的值与以前相同:
#@mock.patch.object(collection, "distinct")
@mock.patch.object(Cursor, "find")
def test_get_some_info(self, mock_find):
date1 = datetime.datetime()
date2 = datetime.datetime()
mock_distinct.return_value = ["id1", "id2"]
find_parameters1 = {"timestamp": {"$lt": date1, "$gt": date2}
find_parameters2 = {"id" : "id1"}
self.my_class.get_some_info(date1, date2)
mock_find.assert_called_with(find_parameters1)
mock_find.assert_any_call(find_parameters2)
<MagicMock name='find().distinct()' id='140089689306448'>
我认为代码总是从集合而不是光标中捕获"不同"值。有人有同样的问题吗?
- 测试参数中的模拟对象应该以相反的顺序排列(有关详细信息,请查看嵌套补丁装饰器(
- 你所说的
mock_collection
应该是mock_find
您的测试代码应该是这样的:
@mock.patch.object(Cursor, "distinct")
@mock.patch.object(Collection, "find")
def test_get_some_info(self, mock_find, mock_distinct):
date1 = datetime.datetime()
date2 = datetime.datetime()
mock_distinct.return_value = ["id1", "id2"]
find_parameters1 = {"timestamp": {"$lt": date1, "$gt": date2}
find_parameters2 = {"id" : "id1"}
self.my_class.get_some_info(date1, date2)
mock_find.assert_called_with(find_parameters1)
mock_find.assert_any_call(find_parameters2)