Writing unit tests should be easy. If I spend effort and time writing unit tests, I’m not sure I’ll write a lot.
Let’s be honest: mocks are the worst part. And how many times did I need to mock a constructor? Enough to know it isn’t easy and write down an article.
Why is mocking constructors such a pain? Well, because constructors work differently, it’s like static method. Let’s see the details.
Problem When Mocking A Constructor With Unittest
Let’s see an example of production code.
from core.my_package import AnotherClass
def my_method():
instance = AnotherClass()
return instance.call()
I want to mock the class AnotherClass because it’s already tested in its own test class. So, let’s only verify that I call the method call().
@patch("core.my_package.AnotherClass", new=lambda: fake_my_method)
def test_my_method():
result = my_method()
assert 1 == result
A simple solution would be using the @patch decorator using the constructor. But when running this, unittest doesn’t mock the constructor at all. What wrong?
The Solution To Mock A Constructor With Unittest
In fact, the way unittest manages the imports is not easy. The only way I found was modifying how I import the class into my method to test.
from core import my_package
def my_method():
instance = my_package.AnotherClass()
return instance.call()
Instead of importing the class in the import line, I need to import the module in the import line. And when instantiating the class, use the module as prefix.
@patch("core.my_package.AnotherClass", new=lambda: fake_my_method)
def test_my_method():
result = my_method()
assert 1 == result
The path annotation should now work perfectly.



Leave a comment