Notice: This page requires JavaScript to function properly.
Please enable JavaScript in your browser settings or update your browser.
Lære Avanceret Mocking i Unittest | Beherskelse af Unittest-Rammeværket
Python Strukturel Programmering

bookAvanceret Mocking i Unittest

I det foregående kapitel så vi vigtigheden af at bruge Mock i testning. Nu ser vi nærmere på de forskellige funktioner og præciserer eventuelle uklare aspekter.

Introduktion til MagicMock

MagicMock er en yderst alsidig implementering af Mock, der understøtter magiske metoder. Den kan bruges til at efterligne adfærden af komplekse objekter i dine tests, som vi så i det forrige kapitel.

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 eksempel bruges MagicMock til at simulere metoden get_account_balance, som normalt ville hente data fra en database.

Brug af mock.patch

@mock.patch bruges til midlertidigt at erstatte de reelle implementeringer af objekter i din kode.

Forestil dig en funktion, der tjekker brugeroplysninger mod en database. Du kan bruge mock.patch for at undgå at tilgå den faktiske database:

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

Nogle gange er det at foretrække at anvende patch() som en context manager fremfor en dekoratør, især når:

  • du kun har brug for at mocke et objekt i en del af testen;
  • eller når overdreven brug af dekoratører eller parametre reducerer testens klarhed.
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-fixturet i Pytest gør det muligt midlertidigt at ændre 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-fixturet gør det muligt sikkert at ændre og håndtere miljøet under testen uden at forårsage bivirkninger uden for testens omfang.

1. Hvilket af følgende kodeeksempler mocker korrekt metoden get_balance til at returnere 500?

2. Hvad tester følgende test?

question mark

Hvilket af følgende kodeeksempler mocker korrekt metoden get_balance til at returnere 500?

Select the correct answer

question mark

Hvad tester følgende test?

Select the correct answer

Var alt klart?

Hvordan kan vi forbedre det?

Tak for dine kommentarer!

Sektion 5. Kapitel 5

Spørg AI

expand

Spørg AI

ChatGPT

Spørg om hvad som helst eller prøv et af de foreslåede spørgsmål for at starte vores chat

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?

bookAvanceret Mocking i Unittest

Stryg for at vise menuen

I det foregående kapitel så vi vigtigheden af at bruge Mock i testning. Nu ser vi nærmere på de forskellige funktioner og præciserer eventuelle uklare aspekter.

Introduktion til MagicMock

MagicMock er en yderst alsidig implementering af Mock, der understøtter magiske metoder. Den kan bruges til at efterligne adfærden af komplekse objekter i dine tests, som vi så i det forrige kapitel.

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 eksempel bruges MagicMock til at simulere metoden get_account_balance, som normalt ville hente data fra en database.

Brug af mock.patch

@mock.patch bruges til midlertidigt at erstatte de reelle implementeringer af objekter i din kode.

Forestil dig en funktion, der tjekker brugeroplysninger mod en database. Du kan bruge mock.patch for at undgå at tilgå den faktiske database:

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

Nogle gange er det at foretrække at anvende patch() som en context manager fremfor en dekoratør, især når:

  • du kun har brug for at mocke et objekt i en del af testen;
  • eller når overdreven brug af dekoratører eller parametre reducerer testens klarhed.
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-fixturet i Pytest gør det muligt midlertidigt at ændre 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-fixturet gør det muligt sikkert at ændre og håndtere miljøet under testen uden at forårsage bivirkninger uden for testens omfang.

1. Hvilket af følgende kodeeksempler mocker korrekt metoden get_balance til at returnere 500?

2. Hvad tester følgende test?

question mark

Hvilket af følgende kodeeksempler mocker korrekt metoden get_balance til at returnere 500?

Select the correct answer

question mark

Hvad tester følgende test?

Select the correct answer

Var alt klart?

Hvordan kan vi forbedre det?

Tak for dine kommentarer!

Sektion 5. Kapitel 5
some-alt