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.patch
returns the mock, so the mockedf2
ismock
, notmock.f2
.From the code you posted, it appears you have a line like
from functions import f1, f2
or
from functions import *
This means that if you monkey-patch
functions.f2
, you are not monkey-patching your local variablef2
.mock
is the same as the mockedfunctions.f2
, butf2
is 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 None
will fail. This is because you mockedf2
. That means the realf2
isn'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 becausef2
has 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()
.