Reputation: 566
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?
Upvotes: 3
Views: 474
Reputation: 11
mock __new__
instead __init__
and assert will be
init.assert_called_once_with(MyClass, "my val")
Upvotes: 0