0
0
PytestHow-ToBeginner ยท 3 min read

How to Mock a Class in pytest: Simple Guide with Examples

To mock a class in pytest, use unittest.mock.patch to replace the class with a mock object during the test. This lets you control the class behavior and test code that depends on it without running its real implementation.
๐Ÿ“

Syntax

Use unittest.mock.patch as a decorator or context manager to replace the target class with a mock. The syntax is:

  • @patch('module.ClassName') to mock the class in a test function.
  • with patch('module.ClassName') as MockClass: to mock within a block.
  • The mock class can be configured to return specific values or track calls.
python
from unittest.mock import patch

@patch('my_module.MyClass')
def test_something(MockClass):
    instance = MockClass.return_value
    instance.method.return_value = 'mocked result'
    # Your test code here
๐Ÿ’ป

Example

This example shows how to mock a class Database in pytest to avoid real database calls and control the return value of its method.

python
from unittest.mock import patch

class Database:
    def connect(self):
        return 'real connection'

    def get_data(self):
        return 'real data'

# Function that uses Database class

def fetch_data():
    db = Database()
    db.connect()
    return db.get_data()

@patch('__main__.Database')
def test_fetch_data(MockDatabase):
    mock_instance = MockDatabase.return_value
    mock_instance.get_data.return_value = 'mocked data'

    result = fetch_data()

    assert result == 'mocked data'
    MockDatabase.assert_called_once()
    mock_instance.connect.assert_called_once()
    mock_instance.get_data.assert_called_once()
โš ๏ธ

Common Pitfalls

Common mistakes when mocking classes in pytest include:

  • Mocking the wrong import path: Always patch the class where it is used, not where it is defined.
  • Not configuring the mock instance: Remember to set return values on MockClass.return_value to simulate instance methods.
  • Forgetting to assert calls: Without assertions, tests may pass without verifying behavior.
python
from unittest.mock import patch

# Wrong patch location example
@patch('my_module.Database')  # Incorrect if fetch_data imports Database differently

def test_wrong_patch(MockDatabase):
    pass  # This test will not mock correctly

# Correct patch location example
@patch('__main__.Database')  # Patch where fetch_data uses Database

def test_correct_patch(MockDatabase):
    pass
๐Ÿ“Š

Quick Reference

Remember these tips when mocking classes in pytest:

  • Use patch('module.ClassName') to mock the class.
  • Access the mock instance with MockClass.return_value.
  • Set method return values on the mock instance.
  • Assert calls to ensure your code interacts with the mock as expected.
โœ…

Key Takeaways

Use unittest.mock.patch to replace classes with mocks in pytest tests.
Patch the class where it is used, not where it is defined, to ensure correct mocking.
Configure the mock instance's methods via MockClass.return_value to simulate behavior.
Always assert mock calls to verify your code interacts correctly with the mocked class.
Use patch as a decorator or context manager depending on test scope.