2015-05-20 11 views
9

mock (http://mock.readthedocs.org/en/latest/index.html) jest doskonałym narzędziem w Pythonie do testu jednostkowego. Może wygodnie kpić z metody, klasy lub dyktatu. Ale natknąłem się na problem, którego nie mogłem znaleźć w prosty sposób.Jak pozwolić MagicMockowi zachowywać się jak dyktando?

to funkcja do badań:

def function_to_be_tested(id, responses): 
    if not id in responses: 
     print '%s not exist'%pole_id 
     return 

    if id in responses.redundantErrorResponses: 
     print '%s is redundant'%pole_id 
     return 

    do_something() 

argumentu odpowiedzi jest dict jak przedmiot, który ma pewne inne cechy (takie jak redundantErrorResponses) z wyjątkiem DICT właściwych funkcji. Teraz chcę skonstruować fałszywe odpowiedzi, aby pozwolić, aby id in responses było prawdziwe, a id in responses.redundantErrorResponses miało być fałszywe. To co mam zrobić: Wystąpił

pole_id = 30 
pole_value = 100 
pole_dic = {pole_id:pole_value} 
mock_responses = MagicMock() 
mock_responses.__getitem__.side_effect = lambda k: pole_dic[k] 
mock_responses.__iter__.side_effect = iter(pole_dic) 
mock_responses.redundantErrorResponses = {} 

Ale błąd:

function_to_be_tested(pole_id, mock_responses) 

>>30 not exist 

jaki sposób można skonstruować obiekt MagicMock tymczasem można iteracyjne jak dict lub w jaki sposób można skonstruować DICT tymczasem obsługują funkcje MagicMock (dodać atrybut swobodnie)?

+0

powinno być '' 'function_to_be_tested (pole_id, mock_responses)' ''? – wwii

Odpowiedz

11

Po co robić bałagan z __iter__? Wydaje mi się, że chcesz zadzierać z __contains__:

>>> import mock 
>>> m = mock.MagicMock() 
>>> d = {'foo': 'bar'} 
>>> m.__getitem__.side_effect = d.__getitem__ 
>>> m.__iter__.side_effect = d.__iter__ 
>>> m['foo'] 
'bar' 
>>> 'foo' in m 
False 
>>> m.__contains__.side_effect = d.__contains__ 
>>> 'foo' in m 
True 
1

Zawsze możesz po prostu stworzyć jakąś głupią klasę, aby zrobić to samo.

In [94]: class MockResponses(dict): 
    ....:  @property 
    ....:  def redundantErrorResponses(self): 
    ....:   return {} 
+0

Byłem bardzo blisko polecania tego samego :-). Jedna uwaga - nawet nie potrzebujesz "właściwości" tutaj - mógłbyś po prostu mieć atrybut "redundantErrorResponses" jako atrybut klasy, ponieważ i tak zamierzasz wykonać tylko 1 wystąpienie ... – mgilson

+0

Tak, to jest moje początkowe rozwiązanie , ale chcę tylko wiedzieć "jak skonstruować obiekt MagicMock, a tymczasem można go powtórzyć jak dyktando". Odpowiedź @ mgilson jest poprawna. – lengxuehx

Powiązane problemy