带有补丁的单元测试行为(Flask) [英] Unit Test Behavior with Patch (Flask)
问题描述
我正在尝试 patch
我的flask api 中的方法,但似乎方法调用没有被替换.app.test_client()
是否做了一些我遗漏的事情.
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.
例如如果我跑
@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()
并检查mstats
,我会取回未模拟的函数.
and inspect mstats
, I will get back the function that is unmocked.
但是,如果我从断点运行 from k.stats import mstats
,我会返回我正在寻找的模拟方法.
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?
推荐答案
这是一个非常令人困惑的概念,但是 patch
的文档尽力解释.
This is a pretty confusing concept, but the documentation of patch
tries its best to explain it.
patch 通过(临时)将一个名称指向的对象更改为另一个名称.可以有许多名称指向任何单个对象,因此要使修补工作,您必须确保修补被测系统使用的名称.
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.
假设 mstats
位于 stats
模块中.您通过 from stats import mstats
在模块 use_stats
中导入它.
Let's say that mstats
lives in module stats
. You're importing it through from stats import mstats
in module use_stats
.
您将要在 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
这篇关于带有补丁的单元测试行为(Flask)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!