【发布时间】:2016-06-17 13:44:09
【问题描述】:
我目前正在尝试为 Main.py 的 main() 函数编写单元测试
这是我的 Main.py 的简化版本:
from Configuration import Configuration # Configuration.py is a file in the same dir
def main():
try:
Configuration('settings.ini')
except:
sys.exit(1) # Test path1
sys.exit(0) # Test path2
if __name__ == '__main__':
main()
在我的Unit Tests\MainUnitTests.py 中,我想导入..\Main.py 并伪造Configuration 类,以便我可以点击Test path1 和Test path2
我发现我可以通过以下方式断言sys.exit():
with self.assertRaises(SystemExit) as cm:
main()
self.assertEqual(cm.exception.code, 1)
但我无法覆盖from Configuration import Configuration
想法?
到目前为止,我在Unit Tests\MainUnitTests.py 中尝试了以下内容:
class FakeFactory(object):
def __init__(self, *a):
pass
sys.modules['Configuration'] = __import__('FakeFactory')
class Configuration(FakeFactory):
pass
另一个演示示例:
foo.py:
from bar import a,b
x = a()
class a(object):
def __init__(self):
self.q = 2
y = a()
print x.q, y.q # prints '1 2' as intended
b() # I want this to print 2 without modifying bar.py
bar.py:
class a(object):
def __init__(self):
self.q = 1
def b():
t = a()
print t.q
【问题讨论】:
-
看看stackoverflow.com/questions/5626193/what-is-a-monkey-patch 实际上它是对您的问题的回答,包括示例
-
@farincz 猴子补丁似乎不起作用。在 MainUnitTest.py 我正在导入
Configuration.py然后在它之后创建一个class Configuration(FakeFactory)...但是Main.py's main()仍在使用Configuration.py中的 Configuration 类,这两个文件似乎没有共享相同的全局名称空间 -
您必须在其上导入配置和补丁配置属性,并且您必须在 main 是第一个 importet 之前执行此操作!比它应该工作
-
@farincz 仍然无法正常工作......请参阅我的问题中的
Another example for demonstration -
当您使用导入
from bar import a时,它会将a直接导入命名空间,因此猴子补丁bar将无济于事,您需要改写main.a。