0Pricing
Python Academy · Lekcja

Mockowanie za pomocą unittest.mock

Proszę izolować testowane jednostki przez mockowanie zależności.

Mockowanie za pomocą unittest.mock to bezpłatna lekcja Python Academy na CoddyKit. To lekcja 4 z 4. Możesz przeczytać całą lekcję poniżej za darmo — a potem ćwiczyć ją interaktywnie w przeglądarce z wbudowanym edytorem kodu i tutorem AI dostępnym 24/7. To część ścieżki edukacyjnej Python Academy, a Twój postęp synchronizuje się między webem a aplikacją CoddyKit. Kurs Python Academy zawiera 4 lekcji w sumie.

Po co używać mocków

Mocki zastępują rzeczywiste zależności (bazy danych, interfejsy API, system plików) kontrolowanymi atrapami, dzięki czemu testy działają szybko, deterministycznie i w izolacji.

from unittest.mock import Mock

api = Mock()
api.get_user.return_value = {"id": 1, "name": "Alice"}

result = api.get_user(1)
print(result)  # {'id': 1, 'name': 'Alice'}

Mock i MagicMock

Mock to klasa bazowa. MagicMock automatycznie konfiguruje metody magiczne/dunder, dzięki czemu może być używany jako iterator, menedżer kontekstu itd.

from unittest.mock import MagicMock

m = MagicMock()
m.__len__.return_value = 5
print(len(m))  # 5

m.__iter__.return_value = iter([1, 2, 3])
for x in m:
    print(x)

patch jako dekorator

Użyj @patch, aby na czas testu zastąpić obiekt w module mockiem.

from unittest.mock import patch

def get_data():
    import requests
    return requests.get("https://api.example.com").json()

@patch("requests.get")
def test_get_data(mock_get):
    mock_get.return_value.json.return_value = {"key": "value"}
    result = get_data()
    assert result == {"key": "value"}

patch jako menedżer kontekstu

Użyj patch() jako menedżera kontekstu, aby ograniczyć zakres mockowania.

from unittest.mock import patch

def test_open():
    with patch("builtins.open", create=True) as mock_open:
        mock_open.return_value.__enter__.return_value.read.return_value = "data"
        with open("file.txt") as f:
            assert f.read() == "data"

patch.object

patch.object(target, attribute) zastępuje konkretny atrybut istniejącego obiektu lub klasy.

from unittest.mock import patch
import mymodule

def test_method():
    with patch.object(mymodule.MyClass, "fetch", return_value=42):
        obj = mymodule.MyClass()
        assert obj.fetch() == 42

Sprawdzanie wywołań

Mocki rejestrują każde wywołanie. Użyj assert_called_once_with, assert_called_with i call_count, aby zweryfikować zachowanie.

from unittest.mock import Mock

send = Mock()
send("hello", to="alice")

send.assert_called_once_with("hello", to="alice")
print(send.call_count)  # 1

return_value i side_effect

Ustaw return_value, aby kontrolować wartość zwracaną przez mock. Użyj side_effect, aby zgłaszać wyjątki lub zwracać różne wartości w kolejnych wywołaniach.

from unittest.mock import Mock

m = Mock(side_effect=[1, 2, ValueError("done")])
print(m())  # 1
print(m())  # 2
m()         # raises ValueError

spec: mocki bezpieczne typowo

Przekaż spec=MyClass, aby ograniczyć mock do atrybutów istniejących w rzeczywistej klasie.

from unittest.mock import Mock

class Calc:
    def add(self, a, b): return a + b

m = Mock(spec=Calc)
m.add(1, 2)         # OK
# m.subtract(1, 2)  # AttributeError: Mock does not have 'subtract'

patch.dict

Użyj patch.dict, aby tymczasowo zmodyfikować słownik (np. zmienne środowiskowe lub konfiguracje na poziomie modułu).

from unittest.mock import patch
import os

def test_env():
    with patch.dict(os.environ, {"DEBUG": "true"}):
        assert os.environ["DEBUG"] == "true"
    assert "DEBUG" not in os.environ

Mocki w pytest za pomocą pytest-mock

pytest-mock udostępnia fixture mocker, który opakowuje unittest.mock i automatycznie sprząta po każdym teście.

# pip install pytest-mock

def test_service(mocker):
    mocker.patch("mymodule.requests.get", return_value=mocker.Mock(
        json=lambda: {"status": "ok"}
    ))
    from mymodule import call_api
    assert call_api()["status"] == "ok"

AsyncMock dla korutyn

Użyj AsyncMock, aby mockować funkcje asynchroniczne, na które czeka się za pomocą await.

from unittest.mock import AsyncMock, patch
import asyncio

async def fetch():
    import httpx
    async with httpx.AsyncClient() as c:
        r = await c.get("https://example.com")
        return r.json()

def test_fetch():
    with patch("httpx.AsyncClient.get", new_callable=AsyncMock) as m:
        m.return_value.json.return_value = {"ok": True}
        result = asyncio.run(fetch())
        assert result["ok"] is True

Szybkie sprawdzenie

Jaki atrybut należy ustawić w obiekcie Mock, aby kontrolować wartość zwracaną podczas jego wywołania?

Podsumowanie

unittest.mock udostępnia Mock, MagicMock, patch i AsyncMock. Używaj return_value i side_effect do kontrolowania zachowania, a metod asercji do weryfikowania sposobu wywołania mocków.

Często zadawane pytania

Czy lekcja „Mockowanie za pomocą unittest.mock” jest bezpłatna?

Tak — pełny tekst „Mockowanie za pomocą unittest.mock” jest dostępny za darmo tutaj w sieci. Aby ćwiczyć ją interaktywnie (wbudowany edytor kodu i tutor AI dostępny 24/7) i odblokować resztę kursu Python Academy, przejdź na CoddyKit PRO. Kurs Python Academy zawiera 4 lekcji w sumie.

Co nauczysz się w „Mockowanie za pomocą unittest.mock”?

Proszę izolować testowane jednostki przez mockowanie zależności. Ćwiczysz Python Academy z praktycznym kodem, który uruchamiasz bezpośrednio w przeglądarce, a tutor AI dostępny 24/7 odpowiada na Twoje pytania podczas pracy nad lekcją.

Czy potrzebuję doświadczenia, aby zacząć Python Academy?

Nie wymagamy żadnego doświadczenia. Python Academy w CoddyKit jest strukturyzowany dla początkujących i zaawansowanych użytkowników, więc możesz zacząć tutaj lub od początku i uczyć się w swoim tempie. To lekcja 4 z 4.

Ile czasu zajmuje lekcja „Mockowanie za pomocą unittest.mock”?

Większość lekcji CoddyKit trwa około 5–10 minut. Każda lekcja to mały, interaktywny krok, dzięki czemu robisz systematyczne postępy i zawsze wracasz dokładnie do tego samego miejsca — na webie i w aplikacji.

Czy mogę pisać i uruchamiać kod w tej lekcji Python Academy?

Tak. Każda lekcja Python Academy zawiera wbudowany edytor kodu, więc piszesz i uruchamiasz prawdziwy kod bezpośrednio w przeglądarce i od razu otrzymujesz sprzężenie zwrotne od AI — bez konfiguracji na komputerze.

Wszystkie lekcje w tym kursie

  1. Pisanie pierwszych testów pytest
  2. Fixtures oraz konfiguracja i sprzątanie
  3. Parametryzacja i pokrycie testami
  4. Mockowanie za pomocą unittest.mock
← Powrót do Python Academy