我正在尝试为一种方法创建一些单一测试,该方法需要使用我不想使用的外部模块中的类来实例化某些对象,因为它们需要在对象初始化时无法传递的参数。 / p>
例如,假设我要测试的代码具有以下结构:
from module_one import Class_1
from module_two import Class_2
class MyMainClass()
def method_to_be_tested(self, stuff):
var_one = Class_1(stuff.data)
self.var_two = Class_2(var_one.data)
print("The var is %s" % self.var_two.attribute)
stuff
是一个复杂的参数,具有几个我无法嘲笑的属性。
这是我使用patch
中的unittest.mock
在测试方法中尝试过的方法(但没有用):
@patch('module_two.Class_2')
@patch('module_one.Class_1')
def test_method(self, mocked_class1, mocked_class2):
stuff = mock()
mocked_class1.return_value = 'some_stuff_that_i_dont_want'
mock_class2 = mock()
mock_class2.attribute = 'what_i_want_to_get'
mocked_class2 = mock_class2
mymainclass.method_to_be_tested(stuff)
assertEqual('what_i_want_to_get', mymainclass.var_two.attribute)
似乎补丁或某些东西不起作用,因为它引发了一个错误,告诉我 str对象没有属性数据,当var_one
时指的是var_one.data
用作Class2
的参数。
我想要的是将任何参数传递给Class2
,并始终获得我在mock_class2
中定义的内容。
编辑::mock()
是从mockito
模块导入的,但是也许我不需要它来实现所需的功能。
答案 0 :(得分:0)
您当然可以在没有模拟的情况下做到这一点。假设在模块MyMainClass
中定义了mainmodule
:
import unittest.mock as mock
class TestMyMainClass(unittest.TestCase):
@mock.patch('mainmodule.Class_2')
@mock.patch('mainmodule.Class_1')
def test_method(self, mocked_class1, mocked_class2):
stuff = mock.Mock()
mocked_class2_instance = mock.Mock()
mocked_class2_instance.attribute = 'what_i_want_to_get'
mocked_class2.return_value = mocked_class2_instance
mymainclass = MyMainClass()
mymainclass.method_to_be_tested(stuff)
self.assertEqual('what_i_want_to_get', mymainclass.var_two.attribute)
if __name__ == '__main__':
unittest.main()
现在,如果您认为此测试很糟糕,我必须同意。
Class_1
,但它甚至没有出现在测试中。Class_2
根本没有意义是不明显的。实际上,您是在测试实现细节,而不是(或除了)可观察到的行为(通常是不好的)。stuff.data
,但是测试将忽略该问题,并将愉快地通过任何检查。还需要一个stuff
属性的data
对象,即使您不在乎它是什么。这里的主要问题是,通过在方法内部实例化Class_1
和Class_2
可以紧密地耦合这三段代码,但是现在您想单独测试它们。这将很困难,并且可能会导致脆弱和难以阅读的测试。
如果您真的希望代码像这样,我建议您在不模拟Class_1
和Class_2
的情况下测试该方法。现在,如果您说您不想这样做,是因为stuff
(或者更好的是stuff.data
;为什么只需要数据时就将整个想法传递给他人?)很难模拟或实例化,我想您的设计有问题,但是据我从您的人为示例中可以得出的结论。