Notice: This page requires JavaScript to function properly.
Please enable JavaScript in your browser settings or update your browser.
Leer Advanced Mocking in Unittest | Mastering Unittest Framework
Python Advanced Concepts

book
Advanced Mocking in Unittest

In the previous chapter, we saw the importance of using Mock in testing. Now, let's take a closer look at the different capabilities and clarify any aspects that were unclear.

Introduction to MagicMock

MagicMock is an incredibly versatile implementation of Mock that supports magic methods. You can use it to mimic the behavior of complex objects in your tests as we saw in previous chapter.

python
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 this example, MagicMock is used to simulate the get_account_balance method, which would typically retrieve data from a database.

Using mock.patch

@mock.patch is used for temporarily replacing the real implementations of objects in your code.

Imagine a function that checks user credentials against a database. You can use mock.patch to avoid hitting the actual database:

python
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 with Context Manager

At times, it's preferable to employ patch() as a context manager instead of a decorator, particularly when:

  • you need to mock an object for just a portion of the test;

  • or when excessive use of decorators or parameters is reducing the clarity of your tests.

python
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 100 # Dummy return value for demonstration

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

Pytest Monkey Patch

The monkeypatch fixture in Pytest lets you temporarily modify classes, modules, or environments during a test.

python
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'

The monkeypatch fixture allows you to safely modify and manage the environment during the test without causing side effects outside the test scope.

1. Which of the following code snippets correctly mocks the get_balance method to return 500?

2. What does the following test check?

question mark

Which of the following code snippets correctly mocks the get_balance method to return 500?

A)
from unittest.mock import MagicMock

class Account:
def get_balance(self):
return 100

account = Account()
account.get_balance = MagicMock(return_value=500)
print(account.get_balance()) # Output 500

B)
from unittest.mock import MagicMock

class Account:
def get_balance(self):
return 100

account = Account()
account.get_balance = MagicMock()
print(account.get_balance(500)) # Output <MagicMock name='mock()' id='...'>

Select the correct answer

question mark

What does the following test check?

import os
import pytest

def get_env_variable():
return os.getenv('API_URL')

def test_get_env_variable(monkeypatch):
monkeypatch.setenv('API_URL', 'https://testapi.com')
assert get_env_variable() == 'https://testapi.com'

Select the correct answer

Was alles duidelijk?

Hoe kunnen we het verbeteren?

Bedankt voor je feedback!

Sectie 5. Hoofdstuk 5

Vraag AI

expand
ChatGPT

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

We use cookies to make your experience better!
some-alt