Notice: This page requires JavaScript to function properly.
Please enable JavaScript in your browser settings or update your browser.
Leer Geavanceerd Mocken in Unittest | Unittest-Framework Beheersen
Python Structureel Programmeren

bookGeavanceerd Mocken in Unittest

In het vorige hoofdstuk zagen we het belang van het gebruik van Mock bij het testen. Nu bekijken we de verschillende mogelijkheden nader en verduidelijken we eventuele onduidelijkheden.

Introductie tot MagicMock

MagicMock is een bijzonder veelzijdige implementatie van Mock die ondersteuning biedt voor magische methoden. Hiermee kun je het gedrag van complexe objecten in je tests nabootsen, zoals we in het vorige hoofdstuk zagen.

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)

In dit voorbeeld wordt MagicMock gebruikt om de methode get_account_balance te simuleren, die normaal gesproken gegevens uit een database zou ophalen.

Gebruik van mock.patch

@mock.patch wordt gebruikt om tijdelijk de echte implementaties van objecten in je code te vervangen.

Stel je een functie voor die gebruikersgegevens controleert tegen een database. Je kunt mock.patch gebruiken om te voorkomen dat de echte database wordt geraadpleegd:

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)

Mocken met Context Manager

Soms is het wenselijker om patch() als contextmanager te gebruiken in plaats van als decorator, met name wanneer:

  • je een object slechts voor een deel van de test wilt mocken;
  • of wanneer overmatig gebruik van decorators of parameters de duidelijkheid van je tests vermindert.
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

De monkeypatch fixture in Pytest maakt het mogelijk om tijdelijk klassen, modules of omgevingen aan te passen tijdens een 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'

De monkeypatch fixture maakt het mogelijk om de omgeving tijdens de test veilig aan te passen en te beheren zonder bijwerkingen buiten de scope van de test te veroorzaken.

1. Welke van de volgende codevoorbeelden mockt de methode get_balance correct om 500 te retourneren?

2. Wat controleert de volgende test?

question mark

Welke van de volgende codevoorbeelden mockt de methode get_balance correct om 500 te retourneren?

Select the correct answer

question mark

Wat controleert de volgende test?

Select the correct answer

Was alles duidelijk?

Hoe kunnen we het verbeteren?

Bedankt voor je feedback!

Sectie 5. Hoofdstuk 5

Vraag AI

expand

Vraag AI

ChatGPT

Vraag wat u wilt of probeer een van de voorgestelde vragen om onze chat te starten.

bookGeavanceerd Mocken in Unittest

Veeg om het menu te tonen

In het vorige hoofdstuk zagen we het belang van het gebruik van Mock bij het testen. Nu bekijken we de verschillende mogelijkheden nader en verduidelijken we eventuele onduidelijkheden.

Introductie tot MagicMock

MagicMock is een bijzonder veelzijdige implementatie van Mock die ondersteuning biedt voor magische methoden. Hiermee kun je het gedrag van complexe objecten in je tests nabootsen, zoals we in het vorige hoofdstuk zagen.

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)

In dit voorbeeld wordt MagicMock gebruikt om de methode get_account_balance te simuleren, die normaal gesproken gegevens uit een database zou ophalen.

Gebruik van mock.patch

@mock.patch wordt gebruikt om tijdelijk de echte implementaties van objecten in je code te vervangen.

Stel je een functie voor die gebruikersgegevens controleert tegen een database. Je kunt mock.patch gebruiken om te voorkomen dat de echte database wordt geraadpleegd:

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)

Mocken met Context Manager

Soms is het wenselijker om patch() als contextmanager te gebruiken in plaats van als decorator, met name wanneer:

  • je een object slechts voor een deel van de test wilt mocken;
  • of wanneer overmatig gebruik van decorators of parameters de duidelijkheid van je tests vermindert.
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

De monkeypatch fixture in Pytest maakt het mogelijk om tijdelijk klassen, modules of omgevingen aan te passen tijdens een 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'

De monkeypatch fixture maakt het mogelijk om de omgeving tijdens de test veilig aan te passen en te beheren zonder bijwerkingen buiten de scope van de test te veroorzaken.

1. Welke van de volgende codevoorbeelden mockt de methode get_balance correct om 500 te retourneren?

2. Wat controleert de volgende test?

question mark

Welke van de volgende codevoorbeelden mockt de methode get_balance correct om 500 te retourneren?

Select the correct answer

question mark

Wat controleert de volgende test?

Select the correct answer

Was alles duidelijk?

Hoe kunnen we het verbeteren?

Bedankt voor je feedback!

Sectie 5. Hoofdstuk 5
some-alt