Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python Unittest is not isolating patches when running tests

I have two tests, each make a different patch on the return value of a method used in my code. When I run the tests separately, they pass. If I run them together, I can see unittest is using the wrong patch for the second test.

I've tried using decorator syntax for patch, I've even had a go at changing the tests to pytest, I've also tried running the tests with nose. I'm running into the same problem, being that the second test gets a result of "foo" instead of "bar".

Is there a way to run the tests sequentially? What have I missed here? Can we assume that I cannot change the classes I'm testing, e.g. using dependency injection instead of patching. Let's assume I have to use patching.

import unittest
from unittest.mock import patch
from unittest.mock import MagicMock
class TestMember(unittest.TestCase):
    def setUp(self):
        pass

    def test_1(self):
        test_json = {
            "something-123": []
        }

        mock = MagicMock()
        mock.return_value = test_json
        with patch('imported_module.get_json', mock):
            from some_module import some_method
            result = some_method()
            self.assertEqual(result, "foo")

    def test_2(self):
        test_json = {
            "something-else-123": []
        }

        mock = MagicMock()
        mock.return_value = test_json
        with patch('imported_module.get_json', mock):
            from some_module import some_method
            result = some_method()
            self.assertEqual(result, "bar")

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

Class I'm testing:

from imported_module import get_json

def some_method():
    json_obj = get_json()
    if "something-123" in json_obj.keys():
        return "foo"
    else:
        return "bar"

and for completeness, here's the imported_module code:

def get_json():
    return {}
like image 974
GDubz Avatar asked Oct 17 '25 13:10

GDubz


1 Answers

You need to patch get_json where it is used (some_module), not where it is defined (imported_module). That's because patch() patches the name used by the code under test.

If you update your patch() to do that, then the tests pass as expected:

with patch('some_module.get_json', mock):

More information about where to patch here.

like image 198
Will Keeling Avatar answered Oct 19 '25 08:10

Will Keeling



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!