Od jakiegoś czasu używamy Mocka dla Pythona.
Teraz mamy sytuację, w której chcemy mockować funkcję
def foo(self, my_param):
#do something here, assign something to my_result
return my_result
Zwykle sposobem na kpienie z tego byłoby (zakładając, że foo jest częścią obiektu)
self.foo = MagicMock(return_value="mocked!")
Nawet jeśli kilka razy wywołam foo (), mogę użyć
self.foo = MagicMock(side_effect=["mocked once", "mocked twice!"])
Teraz mam do czynienia z sytuacją, w której chcę zwrócić stałą wartość, gdy parametr wejściowy ma określoną wartość. Więc jeśli powiedzmy, że „my_param” jest równe „coś”, chcę zwrócić „my_cool_mock”
Wydaje się, że jest to dostępne w mockito dla Pythona
when(dummy).foo("something").thenReturn("my_cool_mock")
Szukałem, jak osiągnąć to samo z Mockiem bez powodzenia?
Jakieś pomysły?
python
unit-testing
mocking
mockito
Juan Antonio Gomez Moriano
źródło
źródło
monkeypatch
. Monkeypatch jest bardziej dla „zastąpienia tej funkcji ze względu na testowanie”, podczas gdy Mock jest tym, czego używasz, gdy chcesz również sprawdzićmock_calls
lub stwierdzić, z czym została wywołana i tak dalej. Jest miejsce na jedno i drugie i często używam obu w różnych momentach w danym pliku testowym.Odpowiedzi:
http://www.voidspace.org.uk/python/mock/mock.html#calling
źródło
side effect
jest to dokładny termin: en.wikipedia.org/wiki/Side_effect_(computer_science)CallableMixin.side_effect
, ale oddzielna funkcja zdefiniowana w przykładzie ma taką samą nazwę.Jak wskazano w obiekcie Python Mock z metodą wywoływaną wielokrotnie
Rozwiązaniem jest napisanie własnego efektu ubocznego
To załatwia sprawę
źródło
Efekt uboczny przyjmuje funkcję (która może być również funkcją lambda ), więc w prostych przypadkach możesz użyć:
źródło
Skończyło się na tym, że szukałem „ jak mockować funkcję na podstawie argumentów wejściowych ” i ostatecznie rozwiązałem ten problem, tworząc prostą funkcję aux:
Teraz:
Mam nadzieję, że to komuś pomoże!
źródło
Możesz również użyć
partial
from,functools
jeśli chcesz użyć funkcji, która przyjmuje parametry, ale funkcja, którą mockujesz, nie. Np. W ten sposób:To zwróci wywoływalny, który nie akceptuje parametrów (jak timezone.now () Django), ale moja funkcja mock_year tak.
źródło
got multiple values for argument
.Żeby pokazać inny sposób:
źródło
Możesz również użyć
@mock.patch.object
:Powiedzmy, że moduł
my_module.py
używapandas
do odczytu z bazy danych i chcielibyśmy przetestować ten moduł metodą mockowaniapd.read_sql_table
(która przyjmujetable_name
jako argument).To, co możesz zrobić, to stworzyć (wewnątrz testu)
db_mock
metodę, która zwraca różne obiekty w zależności od podanego argumentu:W swojej funkcji testowej wykonujesz:
źródło
Jeśli chcesz „zwrócić stałą wartość, gdy parametr wejściowy ma określoną wartość” , być może nawet nie potrzebujesz makiety i możesz użyć
dict
wraz z jejget
metodą:Działa to dobrze, gdy fałszywe wyjście jest mapowaniem wejścia. Gdy jest to funkcja wejścia, sugerowałbym użycie
side_effect
zgodnie z odpowiedzią Amber .Można również użyć kombinacji zarówno jeśli chcesz zachować
Mock
„s możliwości (assert_called_once
,call_count
etc):źródło
Wiem, że to dość stare pytanie, może pomóc jako ulepszenie za pomocą Pythona lamdba
źródło