Автостопом по Python | страница 62



) доступен в стандартной библиотеке. Он позволяет заменять тестируемые части системы mock-объектами и делать предположения о том, как они используются.

Например, вы можете написать обезьяний патч для метода, похожий на тот, что показан в предыдущем примере (обезьяний патч — это код, который модифицирует или заменяет другой существующий код во время работы программы). В этом коде существующий метод с именем ProductionClass.method (в случае если мы создали именованный объект) заменяется новым объектом MagicMock, который при вызове всегда будет возвращать значение 3. Кроме того, этот объект считает количество получаемых вызовов, записывает сигнатуру, с помощью которой был вызван, и содержит методы с выражением, необходимые для тестов:

>from unittest.mock import MagicMock

>instance = ProductionClass()

>instance.method = MagicMock(return_value=3)

>instance.method(3, 4, 5, key='value')

>instance.method.assert_called_with(3, 4, 5, key='value')

Для того чтобы создавать mock-классы и объекты при тестировании, используйте декоратор patch. В следующем примере поиск во внешней системе заменяется mock-объектом, который всегда возвращает одинаковый результат (патч существует только во время работы теста):

>import unittest.mock as mock

>def mock_search(self):

>····class MockSearchQuerySet(SearchQuerySet):

>········def __iter__(self):

>············return iter(["foo", "bar", "baz"])

>····return MockSearchQuerySet()

># SearchForm относится к ссылке на импортированный класс

># myapp.SearchForm и модифицирует этот объект, но не код,

># где определяется сам класс SearchForm

>@mock.patch('myapp.SearchForm.search', mock_search)

>def test_new_watchlist_activities(self):

>····# get_search_results выполняет поиск и итерирует по результату

>····self.assertEqual(len(myapp.get_search_results(q="fish")), 3)

Вы можете сконфигурировать модуль mock и управлять его поведением разными способами. Они подробно описаны в документации к unittest.mock.

doctest

Модуль doctest выполняет поиск фрагментов текста, которые похожи на интерактивные сессии Python в строках документации, а затем выполняет эти сессии, чтобы убедиться, что они работают именно так, как было показано.

Модуль doctest служит другой цели, нежели юнит-тесты. Они обычно менее детальны и не отлавливают особые случаи или регрессионные ошибки. Вместо этого они выступают в качестве содержательной документации основных вариантов использования модуля и его компонентов (в качестве примера можно рассмотреть сценарий «счастливый путь» (happy path —