I have the following toy class:
class MyClass:
def __init__(self, x):
self.x = x
def get_operator(self):
answer = input("Multiply? ")
if answer == "y":
return "multiply"
def multiply(self, y):
if self.get_operator() == "multiply":
return self.x * y
The following test (using pytest) will throw an error:
def test_multiply_is_called(mocker):
multiply = mocker.patch("package.module.MyClass.multiply", return_value=1, autospec=True)
my_instance = MyClass(2)
my_instance.multiply(3)
multiply.assert_called_once() # no error whatever autospec is equal to (True or False)
multiply.assert_called_with(3) # no error only if autospec=False
TypeError: Can't use 'autospec' with create=True
It gets even less clear when trying to mock Python built-in function input
:
def test_input_is_called_once(mocker):
input = mocker.patch("package.module.input", return_value="y", autospec=True)
my_instance = MyClass(2)
my_instance.get_operator()
input.assert_called_once() # no error only if autospec=False
E AssertionError: expected call not found.
E Expected: multiply(3)
E Actual: multiply(<package.module.MyClass object at 0x0000022A4BEEFD00>, 3)
I get that mocking with autospec=True
is a recommended practice, but, obviously, I have a wrong understanding of how it works, despite having read this post and this one, for instance.
Could someone please clarify this subject?