python - Fudge:@patch 当 from X import Y'ing 而不是 import X 时不起作用?

标签 python unit-testing mocking python-import fudge

我在 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()

我应该以不同的方式修补吗?这是 Fudge 的限制还是错误?

最佳答案

您必须在引用对象的位置修补名称,而不是在定义对象的位置。

记住模块只是带有指向其他对象的名称字典的对象(类也是一个对象)。同一对象在不同模块中可以有多个(可能相同)名称。修补使名称暂时指向 Fake 而不是原始对象。

我假设在你的第一个(不工作)some.py模块中你的意思是:

from mdle import Klass

这会创建一个在该模块中使用的名称some.Klass。默认情况下,该名称恰好与 mdle 中的名称匹配,但实际上有两个名称指向同一个类对象。如果您想使用假的,则需要修补 some 中的名称,因为这是用于引用被测试模块中的类的名称。

您的测试补丁 mdle.Klass 这不是 some 中使用的名称,因此您的代码仍然使用其自己的未修补名称来获取真实的类对象。在这种情况下,您需要修补 some.Klass

在第二个(工作中)some.py 中,导入整个 mdle 模块并使用该模块中的名称引用该类。这就是为什么修补 mdle.Klass 在这种情况下有效,您正在修补正在使用的名称。

关于python - Fudge:@patch 当 from X import Y'ing 而不是 import X 时不起作用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28623904/

相关文章:

angular - 如何使用 Injector 在函数中模拟注入(inject)的服务

python - 如何检索对模拟的调用的所有内容?

python - 使用 Docker 部署 flask 应用程序失败,出现 "context.load_cert_chain(' cert.pem' ,'key.pem' ) FileNotFoundError : [Errno 2]"

python - 从matlab中直接在python中使用sklearn

python - 为什么修补析构函数 (__del__) 对失败的测试不起作用?

javascript - 将模拟提供者注入(inject) Angular 单元测试

php - 单元测试 Zend Controller 和模拟一些已执行的操作

ruby-on-rails - 在 Cucumber 场景中使用 Rspec/Mocha stub

python - 如何使用unittest并行执行Selenium Python测试

python - 更改元组列表中元组的第一个值