替换/模拟所有新的类实例

时间:2016-11-07 09:14:48

标签: python python-2.7 unit-testing python-mock

我有以下情况。

class Class1():
    def __init__(self, param1):
        self.param = param1
    def my_func_1(self):
        return "Hello " + self.param1

class Class2():
    def __init__(self):
        self.instance_of_class_1 = Class1('Real')

    def do_it(self):
        return self.instance_of_class_1.my_func_1()

class Class3():
    def __init__(self):
        self.instace_of_class_2 = Class2()

    def do_it(self):
        return self.instace_of_class_2.do_it()

我有一个启动Class3对象的测试,但我想在Class1的构造函数中模拟Class2的新实例。这就是我到目前为止所做的:

def test_my_classes():
    with patch('my.module.Class1') as class_1_mock:
        class_1_mock.my_func_1.return_value = "Hello Fake"
        class_3 = Class3()
        assert class_3.do_it() == 'Hello Fake' #fails

我猜是因为Class1构造函数需要参数 - 它不是一个简单的补丁。

1 个答案:

答案 0 :(得分:0)

您正在嘲笑Class1,但忘记考虑将称为来生成实例。将在调用结果(在实例上)上查找my_func_1

def test_my_classes():
    with patch('my.module.Class1') as class_1_mock:
        class_1_mock.return_value.my_func_1.return_value = "Hello Fake"

Mock并不关心您是否生成了实例,或my_func_1是绑定方法,只是您调用了Class1

如果您希望使用正确的参数调用类,则可以进行断言:

class_1_mock.assert_called_once_with('Real')

演示:

>>> from mock import patch
>>> class Class1():
...     def __init__(self, param1):
...         self.param = param1
...     def my_func_1(self):
...         return "Hello " + self.param1
...
>>> class Class2():
...     def __init__(self):
...         self.instance_of_class_1 = Class1('Real')
...     def do_it(self):
...         return self.instance_of_class_1.my_func_1()
...
>>> class Class3():
...     def __init__(self):
...         self.instace_of_class_2 = Class2()
...     def do_it(self):
...         return self.instace_of_class_2.do_it()
...
>>> with patch('__main__.Class1') as class_1_mock:
...     class_1_mock.return_value.my_func_1.return_value = "Hello Fake"
...     class_3 = Class3()
...     print class_3.do_it() == 'Hello Fake'
...
True
>>> class_1_mock.mock_calls
[call('Real'), call().my_func_1()]

我添加class_1_mock.mock_calls以表明call().my_func_1()已包含在内;这是用于提供Class1('Real')方法调用的my_func_1()实例。