I have function 1 here:
def f1(x):
f2(x 3)
return x * x
And function 2 here:
def f2(y):
print("Whatever you do, don't print this.")
I wrote my test here:
def test_f1(mocker):
mock = mocker.patch("functions.f2")
assert f1(1) == 1
assert f2(1) is None
mock.f2.assert_called_once()
When I run pytest, it throws the error:
> mock.f2.assert_called_once()
E AssertionError: Expected 'f2' to have been called once. Called 0 times.
I literally just called "f2" but it's not picking up on it? Not sure why.
CodePudding user response:
For a number of reasons:
mocker.patchreturns the mock, so the mockedf2ismock, notmock.f2.From the code you posted, it appears you have a line like
from functions import f1, f2or
from functions import *This means that if you monkey-patch
functions.f2, you are not monkey-patching your local variablef2.mockis the same as the mockedfunctions.f2, butf2is no longer the same asfunctions.f2(because it's the originalfunctions.f2, not the mocked one). You can fix this (along with problem #1) with code like:f2 = mocker.patch("functions.f2") # ... f2.assert_called_once()Except now
assert f2(1) is Nonewill fail. This is because you mockedf2. That means the realf2isn't called. Did you mean to do a spy instead of a mock? With a spy, the real function is called. pytest-mock can handle spies, though you might need to change your imports slightly:import functions from functions import f1, f2 def test_f2(mocker): f2 = mocker.spy(functions, 'f2') assert f1(1) == 1 assert f2(1) is None f2.assert_called_once()And now we finally...get a failed
assert_called_once()again, this time becausef2has been called twice. That's because it's called once when you callf1(1), and then a second time when you callf2(1).
CodePudding user response:
You're asserting that mock.f2() was done, not that f2() was done.
I'm not exactly clear on what kind of object your fixture mocker is, nor am I sure I understand what you actually want to do, but perhaps you want mock.assert_called_once()? You can also check mock.mock_calls().
