我有以下配置类:
class ConfigB(object):
Id = None
def __Init__(self, Id):
self.Id = Id
在以下类中实例化并打印属性:
^{pr2}$我创建了下面的测试类来测试它,在这里我试图模拟实例化和cfgB.Id.代码物业电话:
import unittest
import unittest.mock imort MagicMock
import mock
from FileRunner import FileRunner
class TestFileRunner(unittest.TestCase):
@mock.patch('ConfigB.ConfigB.__init__')
@mock.patch('ConfigB.ConfigB.Id')
def test_methodscalled(self, cfgBId, cfgBInit):
fileRunner = FileRunner()
cfgBId.return_value = 17
cfgBInit.return_value = None
print(cfgBId)
fileRunner.runProcess(1)
在调用fileRunner之前,请注意print(cfgBId)语句。我得到以下输出:
<MagicMock name='Id' id='157297352'>
<MagicMock name='Id' id='157297352'>
由于某些原因,当我在测试类中设置返回值时:
cfgBId.return_value = 17
在FileRunner()类中的行上没有调用:
print(cfgB.Id)
要正确显示配置属性,需要做些什么?在
还要注意,我的'ConfigB'类实例化比上面显示的要复杂得多,这就是为什么我要修补实例化和对Id属性的调用。在
*更新:我已经按照@mgilson的建议更改了我的类,但仍然不起作用:
import unittest
import unittest.mock imort MagicMock
import mock
from FileRunner import FileRunner
class TestFileRunner(unittest.TestCase):
@mock.patch('FileRunner.ConfigB')
def test_methodscalled(self, cfgB):
fileRunner = FileRunner()
cfgB.Id = 17
print(cfgBId)
fileRunner.runProcess(1)
我现在从这两个print语句得到以下输出:
<MagicMock name='ConfigB' id='157793640'>
<MagicMock name='ConfigB().Id' id='157020512'>
你知道为什么上面的方法不起作用吗?在
*解决方案:
在对@mgilson建议的测试方法稍作修改后,我得以使其发挥作用:
import unittest
from unittest.mock import MagicMock
import mock
from FileRunner import FileRunner
class TestFileRunner(unittest.TestCase):
@mock.patch('FileRunner.ConfigB')
def test_methodscalled(self, configB):
fileRunner = FileRunner()
cfgB = MagicMock()
cfgB.Id = 17
#This will return the cfgB MagicMock when `ConfigB(Id)` is called in `FileRunner` class
configB.return_value = cfgB
print(cfgB.Id)
fileRunner.runProcess(1)
#To test whether `ConfigB(17)` was called
configB.assert_called_with(17)
我现在得到以下输出:
<MagicMock name='ConfigB' id='157147936'>
17
要使用mock Id属性,您可以使用实例化了该属性的mock来修补类,如下所示:
在我看来,替换
FileRunner
命名空间中的整个ConfigB对象会更好。那么你的测试看起来像这样:注意,
@mock.patch('FileRunner.ConfigB')
将用mock替换FileRunner
命名空间中的ConfigB
类。然后,您可以配置mock以执行任何您喜欢的操作,例如,Id
等于17。在最近,我遇到了一个稍微复杂的问题,我用类似的方法解决了这个问题:为
mock.patch
中使用的mock设置return_value
(如下所示)。在通过使用
mock.patch
作为context manager(linked section中的Ctrl-F“with patch”代替decorator),可以进一步重构您的解决方案,使您能够更好地控制使用的对象:我的例子:断言调用是通过使用修补的对象实例进行的
我想在一些类中测试条件日志(代码示例简化)。测试模块:
^{pr2}$工作测试(解决问题后):
在我提出上述解决方案之前,有问题的部分是:
然后我试了一下:
问题是,我必须以某种方式获取另一个模拟对象,当调用
exception_mock
时返回该对象,并且没有第二次调用exception_mock
。因此,预先创建mock.Mock
实例并分配给return_value
是正确的答案。在相关问题 更多 >
编程相关推荐