猴子补丁一个python函数 - 问题

时间:2016-12-14 11:59:36

标签: python python-2.7 unit-testing monkeypatching

我在使用TestClass

替换不同模块的python函数时遇到了麻烦

我试图测试包含模块中函数的部分代码;更详细的我想要猴子补丁这个功能。

因此,情况类似于以下情况:

模块中的功能

def function_in_module():
    # do some stuff
    return 'ok'

我想测试的部分代码

from dir_1.dir_2.dir_3.module_name import function_in_module
class ExampleClass():
    def __init__(self):
        # do some stuff
        self.var_x = function_in_module()
        # do some stuff again

测试类

from dir_1.dir_2.dir_3 import module_name
class TestClass(TestCase):
    de_monkey = {}
    mp = None

    def setUp(self):
        # save original one
        self.de_monkey['function_in_module'] = module_name.function_in_module()
        if self.mp is None:
            self.mp = MP()

    def tearDown(self):
        # rollback at the end
        module_name.function_in_module = self.de_monkey['function_in_module']

    def test_string(self):
        module_name.function_in_module = self.mp.monkey_function_in_module
        test_obj = ExampleClass()
        self.assertEqual(test_obj.var_x, 'not ok')

class MP(object):

    @staticmethod
    def monkey_function_in_module(self):
        return 'not ok'

正如断言声明所示,预期的结果是“不正常”,但结果是“好”'。

我已经调试了这个,似乎调用函数的不同方式是因为这个猴子补丁不起作用。

实际上,如果我尝试以这种方式调用ExampleClass中的函数

self.var_x = module_name.function_in_module()

正常工作。

我错过了什么?也许这是一种平庸,但它让我发疯了

提前谢谢

1 个答案:

答案 0 :(得分:1)

您的测试代码导入function_in_module并直接引用它。更改module_name.function_in_module的值对代码没有影响。

您应该直接在包含被测代码的模块中替换该函数,而不是在源模块中替换。

请注意,如果您使用mock库,您的生活会更容易,尽管补丁的位置问题仍然相同。