我遇到了Fudge 1.0.3中patch
装饰者的一个奇怪的行为。通过
from <module> import <class>
但导入时工作正常
import <module>
使用相应的代码适应。
这是一个最小化的设置:
mdle.py :
class Klaas(object):
def __init__(self):
# easyest way to signal this class has been instantiated accidently
raise Exception(">:[")
some.py (测试无效):
from mdle import Klaas()
def instantiate():
instance = Klaas()
some.py (测试工作):
import mdle
def instantiate():
instance = mdle.Klaas()
some_test.py :
import unittest
import fudge
import some
class SomeTest(unittest.TestCase):
@fudge.patch("mdle.Klaas")
def test_somethingb(self, Klaas_mock):
klaas_inst = (Klaas_mock.expects_call()
.returns_fake())
# Receiving the exception
some.instantiate()
我应该以不同的方式进行修补吗?这是福吉的限制,还是一个错误?
答案 0 :(得分:1)
您必须修改对象引用的名称,而不是它被定义的位置。
记住模块只是具有指向其他对象的名称的dict的对象(类也是对象)。同一个对象在不同的模块中可以有多个(可能相同的)名称。修补使名称暂时指向Fake
而不是原始对象。
我假设您的第一个(不工作)some.py
模块意味着:
from mdle import Klass
这会创建一个在该模块中使用的名称some.Klass
。默认情况下,名称恰好与mdle
中的名称匹配,但实际上有两个名称指向同一个类对象。如果您想使用假的,那么您需要修补some
中的名称,因为它是用于引用被测模块中的类的名称。
您的测试补丁mdle.Klass
不是some
中使用的名称,因此您的代码仍会使用自己的未修补名称来获取真实的类对象。在这种情况下,您需要修补some.Klass
。
在您的第二个(工作)some.py
中导入整个mdle
模块,并使用该模块中的名称引用该类。这就是为什么修补mdle.Klass
在这种情况下适用的原因,您修补了正在使用的名称。