Python-mock:在同一测试用例中模拟pymongo的Cursor和Collection。



我想对一些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'>

我认为代码总是从集合而不是光标中捕获"不同"值。有人有同样的问题吗?

  1. 测试参数中的模拟对象应该以相反的顺序排列(有关详细信息,请查看嵌套补丁装饰器(
  2. 你所说的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)

最新更新