Python Academy · Lektion

Mockning med unittest.mock

Isolera enheter som testas genom att skapa mockar av beroenden.

Lektion 4 av 413 steg

Mockning med unittest.mock är en gratis lektion i Python Academy på CoddyKit. Detta är lektion 4 av 4. Ni kan läsa hela lektionen gratis nedan och sedan öva praktiskt i webbläsaren med en inbyggd kodredigerare och en AI-handledare som är tillgänglig dygnet runt. Den ingår i lärvägen för Python Academy, och Era framsteg synkroniseras mellan webben och CoddyKit-appen. Kursen i Python Academy innehåller totalt 4 lektioner.

Varför använda mockar?

Mockar ersätter verkliga beroenden (databaser, API:er, filsystem) med kontrollerbara testdubbletter, så att testerna körs snabbt, deterministiskt och isolerat.

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 och MagicMock

Mock är basklassen. MagicMock konfigurerar automatiskt magiska metoder och dunder-metoder, så att den kan användas som iterator, kontexthanterare med mera.

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 som dekorator

Använd @patch för att ersätta ett objekt i en modul med en mock under testets körning.

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 som kontexthanterare

Använd patch() som kontexthanterare för mer lokalt avgränsad mocking.

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) patchar ett specifikt attribut på ett befintligt objekt eller en befintlig klass.

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

Verifiera anrop

Mockar registrerar varje anrop. Använd assert_called_once_with, assert_called_with och call_count för att verifiera beteendet.

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 och side_effect

Ange return_value för att styra vad mocken returnerar. Använd side_effect för att utlösa undantag eller returnera olika värden vid efterföljande anrop.

from unittest.mock import Mock

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

spec: typsäkra mockar

Skicka spec=MyClass för att begränsa mocken till attribut som finns i den riktiga klassen.

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

Använd patch.dict för att tillfälligt ändra en ordlista, till exempel miljövariabler eller konfigurationer på modulnivå.

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

Mocking i pytest med pytest-mock

pytest-mock tillhandahåller en mocker-fixture som omsluter unittest.mock och automatiskt återställer efter varje test.

# 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 för korutiner

Använd AsyncMock för att mocka asynkrona funktioner som inväntas med 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

Snabbkontroll

Vilket attribut anger du på en Mock för att styra vilket värde den returnerar när den anropas?

Sammanfattning

unittest.mock tillhandahåller Mock, MagicMock, patch och AsyncMock. Använd return_value och side_effect för att styra beteendet och assertionsmetoder för att verifiera hur mockarna anropades.

Gratis att börja

Lär dig Python med en AI-lärare – gratis

Skriv och kör riktig kod i webbläsaren, få omedelbar hjälp av en AI-lärare dygnet runt och fortsätt där du slutade – på webben eller i appen.

Kurser
76
Lektioner
320

Vanliga frågor

Är lektionen ”Mockning med unittest.mock” gratis?

Ja – hela texten till ”Mockning med unittest.mock” kan läsas gratis här på webben. Om Ni vill öva interaktivt med en inbyggd kodredigerare och en AI-handledare som är tillgänglig dygnet runt och låsa upp resten av kursen i Python Academy, kan Ni uppgradera till CoddyKit PRO. Kursen i Python Academy innehåller totalt 4 lektioner.

Vad lär jag mig i ”Mockning med unittest.mock”?

Isolera enheter som testas genom att skapa mockar av beroenden. Ni övar på Python Academy med praktisk kod som körs direkt i webbläsaren, medan en AI-handledare som är tillgänglig dygnet runt svarar på Era frågor under lektionen.

Behöver jag någon erfarenhet för att börja lära mig Python Academy?

Du behöver inga förkunskaper. Utbildningen i Python Academy på CoddyKit är upplagd för allt från nybörjare till avancerade elever, så att du kan börja här eller från början och gå fram i din egen takt. Detta är lektion 4 av 4.

Hur lång tid tar lektionen ”Mockning med unittest.mock”?

De flesta CoddyKit-lektioner tar cirka 5–10 minuter. Varje lektion är kort och interaktiv, så att du gör stadiga framsteg och kan fortsätta precis där du slutade – på webben eller i appen.

Kan jag skriva och köra kod i den här Python Academy-lektionen?

Ja. Varje Python Academy-lektion innehåller en inbyggd kodredigerare, så att du kan skriva och köra riktig kod direkt i webbläsaren och få omedelbar AI-feedback – utan lokal installation.

Alla lektioner i den här kursen

  1. Skriva era första pytest-tester
  2. Fixtures och setup/teardown
  3. Parametrisering och testtäckning
  4. Mockning med unittest.mock
← Tillbaka till Python Academy