为什么模拟出zeep.Client无法正常工作?

时间:2018-11-27 10:21:44

标签: python testing mocking

我正在为使用zeep访问SOAP API的一段代码编写单元测试,所以我想模拟出zeep。在我的实际代码中,它看起来像这样:

from zeep import Client

def do_something():
    client = Client("...")

在测试中,我正在这样做:

from unittest import mock

@mock.patch('zeep.Client')
def test_do_somethi(self, MockedClient):
    do_something()

实际功能获得的Client是实际的zeep客户端,而不是我的模拟对象。我也尝试过:

@mock.patch('zeep.client.Client')

结果相同。

我也尝试过:

def test_do_something(self):
  with mock.patch('zeep.client.Client') as MockedClient:
     do_something()

没有区别。

有什么想法为什么不起作用?

2 个答案:

答案 0 :(得分:5)

当模拟不起作用时,首先要查找的是是否在修补正确的名称。

如果您想模拟zeep,但要像导入

from zeep import Client

并且您的测试在同一个文件中,您修补Client而不是zeep.Client。相反,如果您将其导入为

import zeep

,然后在SUT代码中使用zeep.Client,然后修补zeep.Client

如果您要测试位于其他模块(例如mymodule)中的代码,并使用{p>

zeep

然后在您的测试模块中

from zeep import Client # (1)

然后,如果您使用(1)中的替代import mymodule 格式,则修补mymodule.Client,...或mymodule.zeep.Client

答案 1 :(得分:1)

必须从正在使用的文件中修补方法/类。如果您想修补Client并将其导入到 some_file.py 中,则必须从中而不是从lib(zeep.Client

中导入它。

以下是使用Zeep中的official doc的示例。

some_lib.py

from zeep import Client

def do_something():
    wsdl = 'http://www.soapclient.com/xml/soapresponder.wsdl'
    client = zeep.Client(wsdl=wsdl)
    return client.service.Method1('Zeep', 'is cool')

test_connection.py

from some_lib import do_something
from unittest.mock import patch

@patch('some_lib.Client')
def test_do_something(mock_zeep):
    res = do_something()
    assert mock_zeep.call_count == 1


if __name__ == '__main__':
    test_soap_conn()