Notice: This page requires JavaScript to function properly.
Please enable JavaScript in your browser settings or update your browser.
Apprendre Simulation Avancée dans Unittest | Cadre Unittest
Concepts Avancés de Python

bookSimulation Avancée dans Unittest

Dans le chapitre précédent, nous avons vu l'importance d'utiliser Mock lors des tests. Examinons maintenant de plus près les différentes capacités et clarifions les aspects qui pouvaient rester flous.

Introduction à MagicMock

MagicMock est une implémentation extrêmement polyvalente de Mock qui prend en charge les méthodes magiques. Il permet d'imiter le comportement d'objets complexes dans vos tests, comme nous l'avons vu dans le chapitre précédent.

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)

Dans cet exemple, MagicMock est utilisé pour simuler la méthode get_account_balance, qui récupérerait normalement des données depuis une base de données.

Utilisation de mock.patch

@mock.patch est utilisé pour remplacer temporairement les implémentations réelles des objets dans votre code.

Imaginons une fonction qui vérifie les identifiants d'un utilisateur dans une base de données. Vous pouvez utiliser mock.patch pour éviter d'interroger réellement la base de données :

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 avec un gestionnaire de contexte

Il est parfois préférable d'utiliser patch() comme gestionnaire de contexte plutôt que comme décorateur, notamment lorsque :

  • il est nécessaire de mocker un objet uniquement pour une partie du test ;
  • ou lorsque l'utilisation excessive de décorateurs ou de paramètres nuit à la clarté de vos tests.
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

Le fixture monkeypatch dans Pytest permet de modifier temporairement des classes, modules ou environnements pendant un 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'

Le fixture monkeypatch permet de modifier et de gérer l'environnement en toute sécurité pendant le test, sans provoquer d'effets de bord en dehors du périmètre du test.

1. Lequel des extraits de code suivants simule correctement la méthode get_balance pour qu'elle retourne 500 ?

2. Que vérifie le test suivant ?

question mark

Lequel des extraits de code suivants simule correctement la méthode get_balance pour qu'elle retourne 500 ?

Select the correct answer

question mark

Que vérifie le test suivant ?

Select the correct answer

Tout était clair ?

Comment pouvons-nous l'améliorer ?

Merci pour vos commentaires !

Section 5. Chapitre 5

Demandez à l'IA

expand

Demandez à l'IA

ChatGPT

Posez n'importe quelle question ou essayez l'une des questions suggérées pour commencer notre discussion

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?

Awesome!

Completion rate improved to 3.13

bookSimulation Avancée dans Unittest

Glissez pour afficher le menu

Dans le chapitre précédent, nous avons vu l'importance d'utiliser Mock lors des tests. Examinons maintenant de plus près les différentes capacités et clarifions les aspects qui pouvaient rester flous.

Introduction à MagicMock

MagicMock est une implémentation extrêmement polyvalente de Mock qui prend en charge les méthodes magiques. Il permet d'imiter le comportement d'objets complexes dans vos tests, comme nous l'avons vu dans le chapitre précédent.

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)

Dans cet exemple, MagicMock est utilisé pour simuler la méthode get_account_balance, qui récupérerait normalement des données depuis une base de données.

Utilisation de mock.patch

@mock.patch est utilisé pour remplacer temporairement les implémentations réelles des objets dans votre code.

Imaginons une fonction qui vérifie les identifiants d'un utilisateur dans une base de données. Vous pouvez utiliser mock.patch pour éviter d'interroger réellement la base de données :

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 avec un gestionnaire de contexte

Il est parfois préférable d'utiliser patch() comme gestionnaire de contexte plutôt que comme décorateur, notamment lorsque :

  • il est nécessaire de mocker un objet uniquement pour une partie du test ;
  • ou lorsque l'utilisation excessive de décorateurs ou de paramètres nuit à la clarté de vos tests.
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

Le fixture monkeypatch dans Pytest permet de modifier temporairement des classes, modules ou environnements pendant un 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'

Le fixture monkeypatch permet de modifier et de gérer l'environnement en toute sécurité pendant le test, sans provoquer d'effets de bord en dehors du périmètre du test.

1. Lequel des extraits de code suivants simule correctement la méthode get_balance pour qu'elle retourne 500 ?

2. Que vérifie le test suivant ?

question mark

Lequel des extraits de code suivants simule correctement la méthode get_balance pour qu'elle retourne 500 ?

Select the correct answer

question mark

Que vérifie le test suivant ?

Select the correct answer

Tout était clair ?

Comment pouvons-nous l'améliorer ?

Merci pour vos commentaires !

Section 5. Chapitre 5
some-alt