I am trying to patch
methods in my flask api but it appears that the method call is not being replaced. Does app.test_client()
do something under the hood that I am missing.
For example if I run
@patch('k.stats.mstats')
def test_ps(self, mstats):
mstats.return_value = (1, 2, 3)
rv = self.app.get('/ps/')
and I run through the debugger to the point below:
@app.route('/ps/', methods=['GET'])
def ps():
import pdb
pdb.set_trace()
mstats()
and inspect mstats
, I will get back the function that is unmocked.
However, if I run from k.stats import mstats
from the breakpoint, I get back the mocked method that I am looking for.
How do I ensure that the mocked method gets called?
This is a pretty confusing concept, but the documentation of patch
tries its best to explain it.
patch works by (temporarily) changing the object that a name points to with another one. There can be many names pointing to any individual object, so for patching to work you must ensure that you patch the name used by the system under test.
The basic principle is that you patch where an object is looked up, which is not necessarily the same place as where it is defined.
This is why you're able to observe the mocked object when you decide to inject it in; you're observing the patched reference where it's looked up at that moment.
The example does an okay job of explaining what's going on there, but I'll try to clarify.
Let's say that mstats
lives in module stats
. You're importing it through from stats import mstats
in module use_stats
.
You're going to want to mock it in use_stats
, since that's its place of reference.
@patch('use_stats.mstats')
def test_stats(self, mstats):
pass
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