pytest monkeypatch.setattr() inside of test class method

I had exactly the same problem. This works perfectly

import unittest
import pandas as pd
from _pytest.monkeypatch import MonkeyPatch
from src.geipan_data import loadLongitudeLatitudeDateTestimony

class TestGeipanData(unittest.TestCase):

    def setUp(self):
        self.monkeypatch = MonkeyPatch()

    def test_loadLongitudeLatitudeDateTestimony(self):

        def read_csv(*args, **kwargs):
            return pd.DataFrame({
                'obs_date_heure': ['2010-05-21', '1926-05-21'],
                'obs_1_lon': [45.123, 78.4564],
                'obs_1_lat': [32.123, 98.4564],
            })

        self.monkeypatch.setattr(pd, 'read_csv', read_csv)

        df = loadLongitudeLatitudeDateTestimony()

        self.assertListEqual(
            df.columns.values.tolist(),
            ['obs_date_heure', 'obs_1_lon', 'obs_1_lat']
        )

In this example I do mock the pd.read_csv method with monkey patch and I uses asserListEqual that extends from unittest.TestCase


It can't work in this form

While pytest supports receiving fixtures via test function arguments for non-unittest test methods, unittest.TestCase methods cannot directly receive fixture function arguments as implementing that is likely to inflict on the ability to run general unittest.TestCase test suites.

You might create monkeypatch directly

from _pytest.monkeypatch import MonkeyPatch

class MyTest(TestCase):
   def setUp():
     self.monkeypatch = MonkeyPatch()

   def test_classmethod(self):
     self.monkeypatch.setattr ...
     ...

or create own fixture, which will add monkeypatch to your class, and use @pytest.mark.usefixtures

@pytest.fixture(scope="class")
def monkeypatch_for_class(request):
    request.cls.monkeypatch = MonkeyPatch()

@pytest.mark.usefixtures("monkeypatch_for_class")
class MyTest(TestCase):
   def setUp():
     pass

   def test_classmethod(self):
     self.monkeypatch.setattr ...
     ...

Tags:

Python

Pytest