我正在为使用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()
没有区别。
有什么想法为什么不起作用?
答案 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()