21

I have a test class with few test methods and I want to patch some app classes and methods from the test methods. In pytest docs I found an example of how to use monkeypatch module for tests. It that example all tests are just functions, not testclass methods.

But I have a class with test methods:

class MyTest(TestCase):
   def setUp():
     pass

   def test_classmethod(self, monkeypatch):
     # here I want to use monkeypatch.setattr()
     pass

And just passing monkeypatch as method param is obviously doesn't work. So looks like py.test magic doesn't work this way.

So the question is simple and maybe stupid: how can I use monkeypatch.setattr() for pytest inside from the test class method?

2 Answers 2

25

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 ...
     ...
Sign up to request clarification or add additional context in comments.

3 Comments

Shouldn't setUp() function have a self argument?
Hi, wonderful answer. Why in import statement there is underscore before pytest? from _pytest
I also have to add tearDown() with self.monkeypatch.undo()
6

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.