Bawiłem się jedynie MagicMock-iem, chociaż w bibliotece istnieje coś takiego jak Mock. Poniżej trzy, testy do trzech metod, których przetestowanie sprawiło mi problemy. Na początku ważna kwestia, MagicMock jest klasą, więc tworząc obiekt mock-a, należy pamiętać o nawiasach, aby wywołać konstruktor! Za pomocą parametru spec, wskazujemy też klasę, z które zaczerpnięty zostanie interfejs mock-owanej klasy.
Pierwszy z testów (test_show), miał wykazać sekwencyjne zawołanie metody Deciratir.rich(). Robi się to za pomocą dziwnego obiektu call, którego nasyca się atrybutami z jakimi zostanie wywołana mock-owana metoda. Inna kwestia to wartość zwracana. Za pomocą pola return_value, można ustalić jaka wartość będzie zawsze zwracana z mocka.
Drugi test, pokazuje w działaniu jedną z metod (asercji), dostarczoną przez bibliotekę. Tutaj oczekujemy, że metoda zostanie zawołana tylko raz z określonym parametrem (assert_called_once_with).
Trzeci test, również bada, czy mock-i zostały zawołane z określonymi parametrami, ale tym razem, każdy z nich zwraca inną wartość, aby przetestować bardzo specyficzną ścieżkę wykonania programu. Służy temu pole side_effect, z którego pobierane są kolejne zwracane wartości (można też podobna włożyć tam metody, które zostaną zawołane).
#!/usr/bin/env python3 # python -m unittest discover --pattern=test_unittest.py import unittest from unittest.mock import MagicMock from unittest.mock import call class TestPrinter(unittest.TestCase): def setUp(self): self.decorMock = MagicMock(spec=Decorator, name='decorator')() def test_show(self): self.decorMock.rich.return_value = True sut = Printer(self.decorMock) sut.show('asdf') expected = [call.decorMock.attribute.rich('asdf'), call.decorMock.attribute.rich('xxx')] self.assertTrue(self.decorMock.rich.mock_calls == expected) def test_show_once(self): sut = Printer(self.decorMock) sut.show_once() self.decorMock.rich.assert_called_once_with('once') def test_show_comlicated(self): self.decorMock.rich.side_effect = [False, True] sut = Printer(self.decorMock) self.assertEqual(sut.show_complicated(), 2) expected = [call.decorMock.attribute.rich('a'), call.decorMock.attribute.rich('b')] self.assertTrue(self.decorMock.rich.mock_calls == expected) class Decorator(): def rich(self, descr): raise Exception() class Printer(): def __init__(self, decorator): self._decorator = decorator def show(self, descr): self._decorator.rich(descr) if self._decorator.rich('xxx'): return True return False def show_once(self): self._decorator.rich('once') def show_complicated(self): if self._decorator.rich('a'): return 1 if self._decorator.rich('b'): return 2 return 0Z otwartych kwestii, wciąż nie wiem jak testować dowolne parametry przekazywane do mock-a. Testowanie biblioteki do testów trwa nadal.
Brak komentarzy:
Prześlij komentarz