How to Mock open() in Python Using unittest.mock.patch

This code shows how to use unittest.mock.patch with mock_open to test a function that checks if a Git patch can be reverse-applied by reading file content.

Medium Python 3.9+ Aug 9, 2026 Git + Python 15 views 0 copies

Python code

33 lines
Python 3.9+
import unittest
from unittest.mock import patch, mock_open


def apply_reverse_check(file_path, expected_patch):
    """
    Check if a patch can be reverse-applied by comparing file content
    with the expected patch's reverse result.
    """
    try:
        with open(file_path, "r") as f:
            content = f.read()
        if content == expected_patch["reverse"]:
            return "can reverse-apply"
        return "cannot reverse-apply"
    except FileNotFoundError:
        return "file missing"


class TestApplyReverseCheck(unittest.TestCase):
    @patch("builtins.open", new_callable=mock_open, read_data="old content")
    def test_reverse_check_success(self, mock_file):
        result = apply_reverse_check("file.txt", {"reverse": "old content"})
        self.assertEqual(result, "can reverse-apply")

    @patch("builtins.open", new_callable=mock_open, read_data="new content")
    def test_reverse_check_failure(self, mock_file):
        result = apply_reverse_check("file.txt", {"reverse": "old content"})
        self.assertEqual(result, "cannot reverse-apply")


if __name__ == "__main__":
    unittest.main()

Output

stdout
..
----------------------------------------------------------------------
Ran 2 tests in 0.002s

OK

How it works

The @patch("builtins.open", new_callable=mock_open, read_data="...") decorator replaces the built-in open with a mock that returns the specified read_data when .read() is called. This lets you test code that reads files without touching the actual filesystem. The apply_reverse_check function reads the file content and compares it with the expected_patch["reverse"] string, returning a status string. By patching open, you can control the file content for each test, verifying both success and failure paths deterministically. This pattern is essential for unit testing functions that interact with Git patches or file operations in isolation.

Common mistakes

  • Forgetting to patch the correct target; use `builtins.open` not `open` when patching globally.
  • Not passing `new_callable=mock_open`, which leads to a MagicMock that doesn't simulate file reads properly.
  • Using `read_data` without ensuring the function actually calls `.read()` — if it iterates lines, behavior differs.
  • Forgetting to restore the patch after tests if using manual start/stop instead of the decorator.

Variations

  1. Use `with patch("builtins.open", mock_open(read_data="..."))` for context-manager style patching.
  2. Use `pytest` with `monkeypatch` to replace `open` for a more pytest-native approach.

Real-world use cases

  • Testing a function that checks whether a Git patch can be cleanly reverted without actually touching the repo.
  • Validating file-based configuration loaders in unit tests without requiring fixture files on disk.
  • Simulating read-only file access in CI/CD pipelines to verify error handling logic.

Sponsored

Run this sample

Open the browser IDE to tweak the example and see results without installing anything.

Open editor

More from Git + Python

Related tutorials and quizzes for this topic.