2015-04-10 9 views
10

Jak mogę warunkowo wywołać metodę orignal w pozorowaniu?Kpiny warunkowe: wywołanie oryginalnej funkcji, jeśli warunek jest zgodny z

W tym przykładzie chcę tylko sfałszować wartość zwracaną, jeśli bar=='x'. W przeciwnym razie chcę wywołać oryginalną metodę.

def mocked_some_method(bar): 
    if bar=='x': 
     return 'fake' 
    return some_how_call_original_method(bar) 

with mock.patch('mylib.foo.some_method', mocked_some_method): 
    do_some_stuff() 

Wiem, że to trochę dziwne. Jeśli chcę sfałszować mylib.foo.some_method na stronie do_some_stuff(), powinno to być bez warunku. Wszystkie (nie niektóre) połączenia z numerem some_method powinny zostać wyśmiany.

W moim przypadku jest to test integracyjny, a nie mały unittest i mylib.foo.some_method to rodzaj dyspozytora, który bardzo często się wykorzystuje. I w jednym przypadku muszę sfałszować wynik.

Odpowiedz

12

Jeśli chcesz po prostu zastąpić zachowanie bez dbałości o funkcję asocjacyjną mock, możesz użyć argumentu: new; w przeciwnym razie można użyć numeru side_effect, który będzie wywoływał wywołanie.

Domyślam się, że some_method jest metodą obiektową (zamiast staticmethod), więc potrzebujesz odwołania do jej obiektu, aby ją wywołać. Twój wrapper powinien zadeklarować jako pierwszy argument obiekt i twoja poprawka użyć autospec=True, aby użyć poprawnego podpisu dla przypadku side_effect.

Finałowa sztuczka polega na zapisaniu oryginalnego odwołania do metody i wykorzystaniu go do nawiązania połączenia.

orig = mylib.foo.some_method 
def mocked_some_method(self, bar): 
    if bar=='x': 
     return 'fake' 
    return orig(self, bar) 

#Just replace: 
with mock.patch('mylib.foo.some_method', new=mocked_some_method): 
    do_some_stuff() 

#Replace by mock 
with mock.patch('mylib.foo.some_method', side_effect=mocked_some_method, autospec=True) as mock_some_method: 
    do_some_stuff() 
    assert mock_some_method.called 
+0

Co masz na myśli mówiąc "static" tutaj: "Myślę, że some_method is not static ..."? – guettli

+0

Masz rację. makiety jako opakowanie nie jest najlepszą praktyką. Zaktualizowałem pytanie, aby to odzwierciedlić. – guettli

+0

@guettli Z twojego pytania mogę tylko zgadnąć, że 'some_method' nie jest' @ staticmethod', ale metoda obiektowa .... Zmienię swoją odpowiedź, usuwając notatkę boczną, ale powinna już pasować do twoich wymagań. –

Powiązane problemy