I have a class that uses a classmethod as a custom constructor.
# my_module.py class MyClass: def __init__(self, my_arg): self.my_arg = my_arg @classmethod def my_constructor(cls): return cls("my val") I would like to assert in a test that the constructor has been called with a proper value and the instance returned.
I tried several ways of patching, but I couldn’t get it working.
I tried patching the whole class, using the wraps argument to have the real method executed.
# my_test.py from unittest import TestCase from unittest.mock import patch from my_module import MyClass class MyClassTestCase(TestCase): @patch("my_module.MyClass", wraps=MyClass) def test_my_constructor(self, my_class): result = my_class.my_constructor() my_class.assert_called_once_with("my val") self.assertEqual(result, my_class.return_value) The problem here is that the cls argument that the _my_module.MyClass.my_class_ method gets is not my Mock, but the real MyClass class.
My other idea was to use patch.object to patch the real __init__ constructor, but that doesn’t work either. This time because __init__ should not return anything, but MagicMock has a return value.
# my_test.py from unittest import TestCase from unittest.mock import patch from my_module import MyClass class MyClassTestCase(TestCase): @patch.object(MyClass, "__init__") def test_my_constructor(self, init): result = MyClass.my_constructor() init.assert_called_once_with("my val") self.assertEqual(result, init.return_value) Is there an actual way to assert the MyClass class has been instantiated by the _my_constructor_ with the given arguments and returned?