Notice: This page requires JavaScript to function properly.
Please enable JavaScript in your browser settings or update your browser.
Impara Mocking Avanzato in Unittest | Padronanza del Framework Unittest
Practice
Projects
Quizzes & Challenges
Quizzes
Challenges
/
Programmazione Strutturale in Python

bookMocking Avanzato in Unittest

Nel capitolo precedente, abbiamo visto l'importanza dell'utilizzo di Mock nei test. Ora, esaminiamo più da vicino le diverse funzionalità e chiariremo eventuali aspetti poco chiari.

Introduzione a MagicMock

MagicMock è un'implementazione estremamente versatile di Mock che supporta i metodi magici. Puoi utilizzarlo per imitare il comportamento di oggetti complessi nei tuoi test, come visto nel capitolo precedente.

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 questo esempio, MagicMock viene utilizzato per simulare il metodo get_account_balance, che normalmente recupererebbe dati da un database.

Utilizzo di mock.patch

@mock.patch viene utilizzato per sostituire temporaneamente le implementazioni reali degli oggetti nel tuo codice.

Immagina una funzione che verifica le credenziali utente su un database. Puoi usare mock.patch per evitare di accedere realmente al 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 con Context Manager

A volte è preferibile utilizzare patch() come context manager invece che come decoratore, in particolare quando:

  • è necessario fare il mock di un oggetto solo per una parte del test;
  • oppure quando l'uso eccessivo di decoratori o parametri riduce la chiarezza dei test.
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

Il fixture monkeypatch in Pytest consente di modificare temporaneamente classi, moduli o ambienti durante 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'

Il fixture monkeypatch permette di modificare e gestire in modo sicuro l'ambiente durante il test senza causare effetti collaterali al di fuori dell'ambito del test.

1. Quale dei seguenti frammenti di codice esegue correttamente il mock del metodo get_balance per restituire 500?

2. Cosa verifica il seguente test?

question mark

Quale dei seguenti frammenti di codice esegue correttamente il mock del metodo get_balance per restituire 500?

Select the correct answer

question mark

Cosa verifica il seguente test?

Select the correct answer

Tutto è chiaro?

Come possiamo migliorarlo?

Grazie per i tuoi commenti!

Sezione 5. Capitolo 5

Chieda ad AI

expand

Chieda ad AI

ChatGPT

Chieda pure quello che desidera o provi una delle domande suggerite per iniziare la nostra conversazione

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?

bookMocking Avanzato in Unittest

Scorri per mostrare il menu

Nel capitolo precedente, abbiamo visto l'importanza dell'utilizzo di Mock nei test. Ora, esaminiamo più da vicino le diverse funzionalità e chiariremo eventuali aspetti poco chiari.

Introduzione a MagicMock

MagicMock è un'implementazione estremamente versatile di Mock che supporta i metodi magici. Puoi utilizzarlo per imitare il comportamento di oggetti complessi nei tuoi test, come visto nel capitolo precedente.

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 questo esempio, MagicMock viene utilizzato per simulare il metodo get_account_balance, che normalmente recupererebbe dati da un database.

Utilizzo di mock.patch

@mock.patch viene utilizzato per sostituire temporaneamente le implementazioni reali degli oggetti nel tuo codice.

Immagina una funzione che verifica le credenziali utente su un database. Puoi usare mock.patch per evitare di accedere realmente al 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 con Context Manager

A volte è preferibile utilizzare patch() come context manager invece che come decoratore, in particolare quando:

  • è necessario fare il mock di un oggetto solo per una parte del test;
  • oppure quando l'uso eccessivo di decoratori o parametri riduce la chiarezza dei test.
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

Il fixture monkeypatch in Pytest consente di modificare temporaneamente classi, moduli o ambienti durante 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'

Il fixture monkeypatch permette di modificare e gestire in modo sicuro l'ambiente durante il test senza causare effetti collaterali al di fuori dell'ambito del test.

1. Quale dei seguenti frammenti di codice esegue correttamente il mock del metodo get_balance per restituire 500?

2. Cosa verifica il seguente test?

question mark

Quale dei seguenti frammenti di codice esegue correttamente il mock del metodo get_balance per restituire 500?

Select the correct answer

question mark

Cosa verifica il seguente test?

Select the correct answer

Tutto è chiaro?

Come possiamo migliorarlo?

Grazie per i tuoi commenti!

Sezione 5. Capitolo 5
some-alt