在python 3.4中模拟内部对象的实例方法

在python 3.4中模拟内部对象的实例方法,python,unit-testing,python-3.x,mocking,Python,Unit Testing,Python 3.x,Mocking,我的代码中有一个类使用了第三方库。我想模拟通过调用库类的实例方法获得的对象的实例方法。我不清楚如何模拟这个内部对象的实例方法。以下是我的代码: 我的班级: from a import A class MyClass(object): def __init__(self): self.obj = A() def do_something(self): b = self.obj.get_inner_object() result =

我的代码中有一个类使用了第三方库。我想模拟通过调用库类的实例方法获得的对象的实例方法。我不清楚如何模拟这个内部对象的实例方法。以下是我的代码:

我的班级:

from a import A

class MyClass(object):
    def __init__(self):
        self.obj = A()

    def do_something(self):
        b = self.obj.get_inner_object()
        result = b.do_inner()
        return result
这是我的测试课:

from unittest import TestCase
from unittest.mock import MagicMock
from unittest.mock import patch 
from a import A
class TestMyClass(TestCase):
    def __init__(self):
        self.my_class = MyClass()

    @patch.object(A,'get_inner_object')
    def test_do_something(self, mock_get_inner_object):
        test_res = self.my_class.do_something()

正如您在上面看到的,我想模拟我的库的两个方法-get_inner_object()和do_inner(),这是get_inner_object()返回的对象的实例方法。我能够模拟get_inner_object(),但我不清楚如何模拟do_inner()方法。请澄清。以下是我的帮助:

只需模拟所有
A

@patch('a.A')
def test_do_something(self, mock_A):
    mock_b = mock_A.return_value.get_inner_object.return_value
    mock_b.do_inner.return_value = 'mocked return value'

    test_res = self.my_class.do_something()

    self.assertEqual(test_res, 'mocked return value')
毕竟,您在这里测试的是
MyClass
,而不是
A

无论是使用
@patch.object(一个'get\u inner\u object')
还是修补所有
A
self.obj.get\u inner\u object()
表达式调用一个
Mock
实例,因此
.return\u value
属性在该点返回。
do\u internal
方法只是对此处返回的mock的另一个链式调用,因此您可以通过将
.return\u value
属性设置为您测试的对象来设置该方法返回的内容

要将其转换回您的
@patch.object()
情况,
mock\u b
则是
mock\u内部对象。返回值
对象:

@patch.object(A,'get_inner_object')
def test_do_something(self, mock_get_inner_object):
    mock_b = mock_get_inner_object.return_value
    mock_b.do_inner.return_value = 'mocked return value'

    test_res = self.my_class.do_something()

    self.assertEqual(test_res, 'mocked return value')

如果你模拟了
get\u inner\u object
它将返回一个模拟,你可以调用
do\u inner
。当然可以,但是既然我没有把它传递给“MyClass”,那么“MyClass”怎么知道这个模拟对象呢?你说的“知道它”是什么意思?!它不“知道”任何东西,它只是进行调用,如果不能,则抛出一个错误,无论它是否是模拟。从您的示例来看,您似乎应该完全模拟
A
,否则就无法注入它。@RakeshK:
MyClass
直接访问
A
,它已被修补。为什么您需要将任何内容传递给
MyClass
?@MartijnPieters明白了,问题现在已经解决。我按照上述方法设置了我的do\u内部方法的返回值,但是当我运行测试时,我没有得到我在返回值中设置的值,而是得到了我无法验证的对象。你知道我在这里遗漏了什么吗?@RakeshK:那么你的呼叫图还是不同的;您的代码最终调用了一个模拟对象,而您没有为该对象设置
。return\u value
。您可以通过打印
mock\u get\u internal\u对象来检查调用了什么;在那里调用模拟的
A
类,然后在
mockA.return\u value
mock对象上调用
get\u inner\u object()
,然后在该对象上调用
do\u inner()
。因此,上次录制的调用的完整调用图由
moka.return\u value.get\u inner\u object.return\u value.do\u inner.return\u value
复制。我可以通过将“return\u object”更改为“return\u value”来解决这个问题。不完全确定为什么会这样,但解决了这个问题。你能帮我理解吗?@RakeshK:啊!那是我的错别字。对不起!我确实测试了这个方法,但在键入答案时,我只是打错了。