2016-01-29 4 views
1

Я хочу сделать макетный тест для некоторых запросов mongo, но у меня была проблема, когда я попытался издеваться над двумя разными предметами манго (Cursor и Collection) в такой же объем. Я не могу поместить здесь оригинальный код, но я сделал общий с той же проблемой.Python-mock: насмешливый курсор и коллекция pymongo в том же тестовом случае

Это функция, которую я хочу проверить (с помощью функции поиска и различны):

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 call not found' % expected_string AssertionError: find({"id" : "id1"}) call not found

Так я напечатал значение 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'> 

Я думаю, что код всегда захватывает «отличное» значение из коллекции, а не из курсора. У кого-то была такая же проблема?

ответ

0
  1. издевается объекты испытаний аргументы должны быть в обратном порядке (взгляните на Nesting Patch Decorators подробности)
  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) 
+0

Спасибо за ваш ответ, это была моя ошибка. В моем исходном коде порядок декораторов правильный. Я изменил параметры сейчас –

+0

@DiegoPereira, пожалуйста, объясните, что такое 'mock_connection' в вашем примере –

+0

Взгляните на свой журнал:' connection' - это макет, и вы называете метод 'find' 'mock –