Assuming I have a function that takes a complex object and does something with it:
def foo(bar: SomeComplexObject):
...
In unit tests bar
will be replaced by a mock object, but that of courses now raises type warnings. Should I simply ignore or suppress these or is there a proper way to deal with them (without changing the original function signature of course)?
Update: I've seen now that this is an open issue on mypy, but its been in that state for over two years. Has any consensus emerged on how to work around this?
Mocking is a very common testing mechanism, and it is a bad idea. This post details why you should not use mocking, and why and how you should write integration tests instead. TL;DR: Mocking provides false confidence by hiding real failures.
Mocking is used in unit tests to replace the return value of a class method or function. This may seem counterintuitive since unit tests are supposed to test the class method or function, but we are replacing all those processing and setting a predefined output.
Mocking is a process used in unit testing when the unit being tested has external dependencies. The purpose of mocking is to isolate and focus on the code being tested and not on the behavior or state of external dependencies.
I'm going to put my 2¢ in and say that you should type-check your testsuite. Its still code and static type checking will help you write better code faster.
That leaves the question of how. Ideally, if your function expects SomeComplexObject
then you also pass in an instance thereof. Either by building one in your test fixtures, or by subclassing and overriding what you don't need. The best unit test is the one that operates on proper input.
That still leaves the case where this is impractical or we explicitly want to test how invalid input is handled. In that case just explicitly cast your mock to the type that mypy requires:
from typing import cast
def test_foo():
mock_bar = cast(SomeComplexObject, MockBar())
foo(mock_bar)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With