potrzebne trzy metody patch (_send_reply
, _reset_watchdog
i _handle_set_watchdog
) z metod próbnych przed badaniem połączenia z czwartym sposobem (_handle_command
) w teście jednostkowej kopalni.korzystny sposób łatania wiele metod Pythona badanej jednostki
Od patrząc na dokumentacji pakietu mock, istnieje kilka sposobów, mogę iść o nim:
Z patch.multiple
jako dekorator
@patch.multiple(MBG120Simulator,
_send_reply=DEFAULT,
_reset_watchdog=DEFAULT,
_handle_set_watchdog=DEFAULT,
autospec=True)
def test_handle_command_too_short_v1(self,
_send_reply,
_reset_watchdog,
_handle_set_watchdog):
simulator = MBG120Simulator()
simulator._handle_command('XA99')
_send_reply.assert_called_once_with(simulator, 'X?')
self.assertFalse(_reset_watchdog.called)
self.assertFalse(_handle_set_watchdog.called)
simulator.stop()
Z patch.multiple
jako kierownik kontekstowego
def test_handle_command_too_short_v2(self):
simulator = MBG120Simulator()
with patch.multiple(simulator,
_send_reply=DEFAULT,
_reset_watchdog=DEFAULT,
_handle_set_watchdog=DEFAULT,
autospec=True) as mocks:
simulator._handle_command('XA99')
mocks['_send_reply'].assert_called_once_with('X?')
self.assertFalse(mocks['_reset_watchdog'].called)
self.assertFalse(mocks['_handle_set_watchdog'].called)
simulator.stop()
z wieloma patch.object
decoratorations
@patch.object(MBG120Simulator, '_send_reply', autospec=True)
@patch.object(MBG120Simulator, '_reset_watchdog', autospec=True)
@patch.object(MBG120Simulator, '_handle_set_watchdog', autospec=True)
def test_handle_command_too_short_v3(self,
_handle_set_watchdog_mock,
_reset_watchdog_mock,
_send_reply_mock):
simulator = MBG120Simulator()
simulator._handle_command('XA99')
_send_reply_mock.assert_called_once_with(simulator, 'X?')
self.assertFalse(_reset_watchdog_mock.called)
self.assertFalse(_handle_set_watchdog_mock.called)
simulator.stop()
metody Ręczna wymiana użyciu create_autospec
def test_handle_command_too_short_v4(self):
simulator = MBG120Simulator()
# Mock some methods.
simulator._send_reply = create_autospec(simulator._send_reply)
simulator._reset_watchdog = create_autospec(simulator._reset_watchdog)
simulator._handle_set_watchdog = create_autospec(simulator._handle_set_watchdog)
# Exercise.
simulator._handle_command('XA99')
# Check.
simulator._send_reply.assert_called_once_with('X?')
self.assertFalse(simulator._reset_watchdog.called)
self.assertFalse(simulator._handle_set_watchdog.called)
Osobiście myślę, że ten ostatni jest najwyraźniejszy czytać, i nie spowoduje potwornie długich kolejkach jeżeli liczba wyśmiewanych metod rośnie. Pozwala to również uniknąć konieczności przekazywania simulator
jako pierwszego argumentu (self
) do assert_called_once_with
.
Ale żadna z nich nie jest szczególnie miła. Zwłaszcza podejście wielokrotne patch.object
, które wymaga starannego dopasowywania porządku parametrów do zagnieżdżonych dekoracji.
Czy jest jakieś podejście, które przeoczyłem, lub sposób na uczynienie tego bardziej czytelnym? Co robisz, gdy musisz załatać wiele metod na testowanej instancji/klasie?
Bardzo dziękuję za dokładną odpowiedź. W celu: 1) Dobrze, że moja sprawa jest wyjątkowa (że mam dostęp do instancji et.c.). 2) Dzięki za napiwek o JAKIKOLWIEK. 3) Tak, być może przesadzam kruchość kolejności argumentów podczas używania dekoratorów. 4) Pytanie: Tak więc '@patch ('package.module.Class.some_method', autospec = True)' jest równoważne '@ patch.object (package.module.Class, 'some_method', autospec = True)'? To miło, a jeśli tak, to wolę twój sposób robienia tego. ... – estan
... 5) Jestem nieco niezdecydowany, aby użyć 'setUp' i' tearDown', ponieważ podoba mi się, że moje testy są całkowicie niezależne, mimo że będzie to oznaczać więcej pisania. Ale to tylko osobiste preferencje. 6) .. i na tej notatce, tak przepraszam, że zadaję pytanie, które ma głównie subiektywne odpowiedzi! 7) Zastanowię się nad tym, co powiedziałeś o testowaniu prywatnych metod. W Pythonie bardzo mi się to podoba i ważne jest, aby ten kod miał 100% zasięgu linii. Ale rozważę podzielenie ich na współpracowników. Testowana klasa jest jednak niewielka. Jeszcze raz dziękuję za wspaniałą odpowiedź. – estan
Gah. Przepraszamy za okropne formatowanie. Naprawdę nie jestem przyjaciółmi z funkcją komentowania SO. W każdym razie, akceptując twoją odpowiedź, ponieważ jest bardzo dobra. – estan