0

I am trying to replace a function with itself, using different parameters.

Here is a sample. I can't share the real code, I'm on papery secrecy!

import unittest
from unittest.mock import patch

import mymodule
import production

class MyTest(unittest.TestCase):
    
    @patch('production.mymodule.myfunction', lambda: mymodule.myfunction(devmode=True))
    def test_main_with_mymodule_function_does_not_raise_exception(self):
        # This is an integration test. myfunction is used within main.
        try:
            production.main()
        except Exception as e:
            self.fail(e)

As expected the following generates a recursive call:

@patch('production_code.mymodule.myfunction', lambda: mymodule.myfunction(devmode=True))

We basically decorate myfunction with a decorator that will call myfunction. We get a nice "Too many recursions" exception!

I need a way to replace myfunction(devmode=False) with myfunction(devmode=True). But because I am in an integration test, and testing main(), I have no direct access to the function's parameters. Thing is, I made this very integration test to test how myfunction integrates with everything else in main.

Ideally, I shouldn't even have to create a devmode parameter, but I'm running a heavy sql query that requires to be limited by adding "TOP(10)" to the query.

Thanks for your help! :)

1 Answer 1

2

You can keep a reference to the unpatched function before your test runs. Use that in the patch call:

import unittest
from unittest.mock import patch


def iut(devmode=False):
    print(devmode)


class MyTest(unittest.TestCase):
    _unpatched = iut   # keep reference to unpatched IUT

    @patch('so_test.iut', lambda *args, **kwargs: MyTest._unpatched(devmode=True))
    def test(self):
        try:
            iut()
        except Exception as e:
            self.fail(e)

This results in the following, indicating devmode was set to True:

True

Note: you might need to pass args, kwargs to _unpatched depending in your function.

Sign up to request clarification or add additional context in comments.

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.