Notice: This page requires JavaScript to function properly.
Please enable JavaScript in your browser settings or update your browser.
Lære Avansert Mocking i Unittest | Beherske Unittest-rammeverket
Practice
Projects
Quizzes & Challenges
Quizzes
Challenges
/
Python Strukturert Programmering

bookAvansert Mocking i Unittest

I forrige kapittel så vi viktigheten av å bruke Mock i testing. Nå skal vi se nærmere på de ulike mulighetene og klargjøre eventuelle uklare aspekter.

Introduksjon til MagicMock

MagicMock er en svært allsidig implementasjon av Mock som støtter magiske metoder. Du kan bruke den til å etterligne oppførselen til komplekse objekter i testene dine, slik vi så i forrige kapittel.

from unittest.mock import MagicMock
import unittest

class BankAccount:
    def __init__(self, id):
        self.id = id
        self.balance = self.get_account_balance(id)

    def get_account_balance(self, id):
        # Simulates a database call
        pass

class TestBankAccount(unittest.TestCase):
    def test_balance_retrieval(self):
        account = BankAccount(1)
        account.get_account_balance = MagicMock(return_value=1000)
        self.assertEqual(account.balance, 1000)

I dette eksempelet brukes MagicMock til å simulere get_account_balance-metoden, som vanligvis henter data fra en database.

Bruk av mock.patch

@mock.patch brukes for midlertidig å erstatte de faktiske implementasjonene av objekter i koden din.

Tenk deg en funksjon som sjekker brukerinformasjon mot en database. Du kan bruke mock.patch for å unngå å koble til den faktiske databasen:

from unittest.mock import patch
import unittest

def authenticate(username, password):
    # Assume this function checks credentials against a database
    pass

class TestAuthentication(unittest.TestCase):
    @patch('module_containing.authenticate')
    def test_login(self, mock_auth):
        mock_auth.return_value = True
        response = authenticate('user', 'pass')
        self.assertTrue(response)

Mocking med Context Manager

Noen ganger er det å foretrekke å bruke patch() som en context manager i stedet for en dekoratør, spesielt når:

  • du trenger å mocke et objekt kun for en del av testen;
  • eller når overdreven bruk av dekoratører eller parametere reduserer lesbarheten i testene dine.
from unittest.mock import patch
import unittest

class BankAccount:
    def __init__(self, id):
        self.id = id
        self.balance = self.get_account_balance(id)

    def get_account_balance(self, id):
        # Simulates a database call
        return 0

class TestBankAccount(unittest.TestCase):
    def test_balance_retrieval(self):
        with patch.object(BankAccount, 'get_account_balance', return_value=1000) as mock_get:
            account = BankAccount(1)
            self.assertEqual(account.balance, 1000)
            mock_get.assert_called_once_with(1)

Pytest Monkey Patch

monkeypatch-fixture i Pytest lar deg midlertidig endre klasser, moduler eller miljøer under en test.

import os
import pytest

def test_api_url(monkeypatch):
    # Set the API_URL environment variable to a test URL
    monkeypatch.setenv('API_URL', 'https://testapi.com')

    # Now check that the environment variable was set correctly
    assert os.environ['API_URL'] == 'https://testapi.com'

monkeypatch-fixture gjør det mulig å trygt endre og håndtere miljøet under testen uten å forårsake bivirkninger utenfor testens omfang.

1. Hvilken av følgende kodeeksempler mocker metoden get_balance korrekt slik at den returnerer 500?

2. Hva tester følgende test?

question mark

Hvilken av følgende kodeeksempler mocker metoden get_balance korrekt slik at den returnerer 500?

Select the correct answer

question mark

Hva tester følgende test?

Select the correct answer

Alt var klart?

Hvordan kan vi forbedre det?

Takk for tilbakemeldingene dine!

Seksjon 5. Kapittel 5

Spør AI

expand

Spør AI

ChatGPT

Spør om hva du vil, eller prøv ett av de foreslåtte spørsmålene for å starte chatten vår

Suggested prompts:

Can you explain the difference between Mock and MagicMock?

How does mock.patch work with classes and methods?

When should I use a context manager instead of a decorator for patching?

bookAvansert Mocking i Unittest

Sveip for å vise menyen

I forrige kapittel så vi viktigheten av å bruke Mock i testing. Nå skal vi se nærmere på de ulike mulighetene og klargjøre eventuelle uklare aspekter.

Introduksjon til MagicMock

MagicMock er en svært allsidig implementasjon av Mock som støtter magiske metoder. Du kan bruke den til å etterligne oppførselen til komplekse objekter i testene dine, slik vi så i forrige kapittel.

from unittest.mock import MagicMock
import unittest

class BankAccount:
    def __init__(self, id):
        self.id = id
        self.balance = self.get_account_balance(id)

    def get_account_balance(self, id):
        # Simulates a database call
        pass

class TestBankAccount(unittest.TestCase):
    def test_balance_retrieval(self):
        account = BankAccount(1)
        account.get_account_balance = MagicMock(return_value=1000)
        self.assertEqual(account.balance, 1000)

I dette eksempelet brukes MagicMock til å simulere get_account_balance-metoden, som vanligvis henter data fra en database.

Bruk av mock.patch

@mock.patch brukes for midlertidig å erstatte de faktiske implementasjonene av objekter i koden din.

Tenk deg en funksjon som sjekker brukerinformasjon mot en database. Du kan bruke mock.patch for å unngå å koble til den faktiske databasen:

from unittest.mock import patch
import unittest

def authenticate(username, password):
    # Assume this function checks credentials against a database
    pass

class TestAuthentication(unittest.TestCase):
    @patch('module_containing.authenticate')
    def test_login(self, mock_auth):
        mock_auth.return_value = True
        response = authenticate('user', 'pass')
        self.assertTrue(response)

Mocking med Context Manager

Noen ganger er det å foretrekke å bruke patch() som en context manager i stedet for en dekoratør, spesielt når:

  • du trenger å mocke et objekt kun for en del av testen;
  • eller når overdreven bruk av dekoratører eller parametere reduserer lesbarheten i testene dine.
from unittest.mock import patch
import unittest

class BankAccount:
    def __init__(self, id):
        self.id = id
        self.balance = self.get_account_balance(id)

    def get_account_balance(self, id):
        # Simulates a database call
        return 0

class TestBankAccount(unittest.TestCase):
    def test_balance_retrieval(self):
        with patch.object(BankAccount, 'get_account_balance', return_value=1000) as mock_get:
            account = BankAccount(1)
            self.assertEqual(account.balance, 1000)
            mock_get.assert_called_once_with(1)

Pytest Monkey Patch

monkeypatch-fixture i Pytest lar deg midlertidig endre klasser, moduler eller miljøer under en test.

import os
import pytest

def test_api_url(monkeypatch):
    # Set the API_URL environment variable to a test URL
    monkeypatch.setenv('API_URL', 'https://testapi.com')

    # Now check that the environment variable was set correctly
    assert os.environ['API_URL'] == 'https://testapi.com'

monkeypatch-fixture gjør det mulig å trygt endre og håndtere miljøet under testen uten å forårsake bivirkninger utenfor testens omfang.

1. Hvilken av følgende kodeeksempler mocker metoden get_balance korrekt slik at den returnerer 500?

2. Hva tester følgende test?

question mark

Hvilken av følgende kodeeksempler mocker metoden get_balance korrekt slik at den returnerer 500?

Select the correct answer

question mark

Hva tester følgende test?

Select the correct answer

Alt var klart?

Hvordan kan vi forbedre det?

Takk for tilbakemeldingene dine!

Seksjon 5. Kapittel 5
some-alt