[英]Python unittest mock configuration not proliferating to test method
我有一个想在测试中模拟的复杂类。 但是,我希望能够在我的模拟类上设置一个特定的属性,以便我的被测函数能够正常工作。 下面是具有实际和预期输出的简单,可运行的示例。
在我的示例中,为什么我的模拟配置不会激增到my_module.instantiate_class_do_stuff
? 显然, MyClass
确实在被嘲笑,但是我配置MyClass.a
的模仿的尝试并没有坚持。
目录tmp
内容:
tmp
├── __init__.py
├── my_module.py
└── test_my_module.py
请注意__init__.py
为空。
文件my_module.py
内容:
class MyClass:
def __init__(self):
# Do expensive operations that will be mocked in testing.
self.a = 7
def instantiate_class_do_stuff():
"""Create MyClass instance and do stuff with it"""
instance = MyClass()
print('Value of a in instantiate_class_call_method: {}'.format(instance.a))
# Do stuff with instance...
文件test_my_module.py
内容:
import unittest
from unittest.mock import patch
from tmp import my_module
class MyTestCase(unittest.TestCase):
def setUp(self):
print('*' * 79)
def test_create_class_call_method_1(self):
"""Try using the Mock's configure_mock method."""
with patch('tmp.my_module.MyClass') as p:
p.configure_mock(a=10)
print('Value of a in test_create_class_call_method_1: {}'
.format(p.a))
my_module.instantiate_class_do_stuff()
self.assertTrue(True)
def test_create_class_call_method_2(self):
"""Try passing in kwargs to patch, which should make it to
configure_mock, according to the docs.
"""
with patch('tmp.my_module.MyClass', a=10) as p:
print('Value of a in test_create_class_call_method_2: {}'
.format(p.a))
my_module.instantiate_class_do_stuff()
self.assertTrue(True)
def test_create_class_call_method_alternate_2(self):
"""Try using patch.object instead of plain patch."""
with patch.object(my_module, 'MyClass', a=10) as p:
print('Value of a in test_create_class_call_method_3: {}'
.format(p.a))
my_module.instantiate_class_do_stuff()
self.assertTrue(True)
if __name__ == '__main__':
unittest.main()
运行test_my_module.py
实际输出:
*******************************************************************************
Value of a in test_create_class_call_method_1: 10
Value of a in instantiate_class_call_method: <MagicMock name='MyClass().a' id='140029598201104'>
*******************************************************************************
Value of a in test_create_class_call_method_2: 10
Value of a in instantiate_class_call_method: <MagicMock name='MyClass().a' id='140029598270096'>
*******************************************************************************
Value of a in test_create_class_call_method_3: 10
Value of a in instantiate_class_call_method: <MagicMock name='MyClass().a' id='140029598347088'>
来自运行test_my_module.py
预期输出:
*******************************************************************************
Value of a in test_create_class_call_method_1: 10
Value of a in instantiate_class_call_method: 10
*******************************************************************************
Value of a in test_create_class_call_method_2: 10
Value of a in instantiate_class_call_method: 10
*******************************************************************************
Value of a in test_create_class_call_method_3: 10
Value of a in instantiate_class_call_method: 10
那么,当被测函数实际运行时,如何使属性配置有效?
好吧,这对我来说当然不是很直观,但是我发现了。
我注意到在我的测试方法中, p
的值( MyClass
的__repr__
实例)具有__repr__
如<MagicMock name='MyClass' id='140054079807440'>
。
然而,在测试中,在函数内部instantiate_class_do_stuff
,的值instance
具有__repr__
像<MagicMock name='MyClass()' id='140054079941392'>
区别在于MyClass
之后的()
。
因此,看来我不是在模拟正确的东西-我想在MyClass
的返回值上模拟a
属性。
因此,工作测试如下所示:
def test_creat_class_call_method(self):
# Create a mock which will be returned by MyClass.
m = MagicMock()
m.a = 10
with patch('tmp.my_module.MyClass', return_value=m) as p:
my_module.instantiate_class_do_stuff()
并且my_module.instantiate_class_do_stuff
的print
语句打印以下内容:
Value of a in instantiate_class_do_stuff: 10
成功!
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.