Monkey在模块中修补功能以进行单元测试

ozg*_*gur 5 python unit-testing monkeypatching

我在调用从另一个模块导入的另一个方法的模块中有以下方法:

def imported_function():
    do_unnecessary_things_for_unittest()
Run Code Online (Sandbox Code Playgroud)

需要测试的实际方法,导入并使用上述功能:

from somewhere import imported_function

def function_to_be_tested():
    imported_function()
    do_something_more()
    return 42
Run Code Online (Sandbox Code Playgroud)

内部呼叫和内部相关计算imported_function并不重要,他们是不是我想要测试,所以我只是想跳过他们,而测试的实际功能是什么function_to_be_tested.

因此,我试图在测试方法内部的某个地方修补模块,但没有运气.

def test_function_to_be_tested(self):
    import somewhere
    somewhere.__dict__['imported_function'] = lambda : True
Run Code Online (Sandbox Code Playgroud)

问题是,如何在测试时修补模块的方法,以便在测试阶段不会调用它?

lya*_*pun 14

我认为最好使用Mock Library

所以你可以这样做:

from somewhere import imported_function

@patch(imported_function)
def test_function_to_be_tested(self, imported_function):
    imported_function.return_value = True
    #Your test
Run Code Online (Sandbox Code Playgroud)

我认为对于单元测试,它比猴子补丁更好.

  • 我不得不做`@patch('imported_function')`来使它工作. (2认同)

slo*_*oth 8

假设您有以下文件:

somewhere.py

def imported_function():
    return False
Run Code Online (Sandbox Code Playgroud)

testme.py

from somewhere import imported_function

def function_to_be_tested():
    return imported_function()
Run Code Online (Sandbox Code Playgroud)

打电话testme.function_to_be_tested()会回来False.


现在,诀窍是导入somewhere 之前 testme:

import somewhere
somewhere.__dict__['imported_function'] = lambda : True

import testme
def test_function_to_be_tested():
    print testme.function_to_be_tested()

test_function_to_be_tested()
Run Code Online (Sandbox Code Playgroud)

输出:

真正


或者,重新加载testme模块

import testme

def test_function_to_be_tested():
    print testme.function_to_be_tested()
    import somewhere
    somewhere.__dict__['imported_function'] = lambda : True
    print testme.function_to_be_tested()
    reload(testme)
    print testme.function_to_be_tested()

test_function_to_be_tested()
Run Code Online (Sandbox Code Playgroud)

输出: