在Python中从WSDL文件创建模拟Web服务
我们正在为一个远程服务编写客户端,这个服务提供了SOAP网络服务,并且发布了这些服务的WSDL定义。
在测试期间,我们无法访问系统,所以我们想写一个模拟服务。我们使用Python来编写客户端,因此理想情况下,我们也希望用Python来创建模拟服务器,虽然我想这并不是绝对必要的。
我们的理想情况是能够从WSDL文件生成一些代码模板,然后我们可以填充这些模板,最后用Paste Deploy作为WSGI服务器来提供这些服务。不过,只要能可靠地工作,使用的服务器不一定非得是Paste Deploy或WSGI。最重要的是,我们需要从“真实”的WSDL文件生成这些代码模板,以免不小心写出一个不合规的模拟服务器。
我们在客户端使用suds这个库,并且也看过soaplib和ZSI。不过,soaplib里的wsgi2py部分在开头就说“不要使用”,而ZSI看起来又比较复杂。大家一般会用什么来处理这种情况呢?
马丁
3 个回答
你可以用这段代码来创建一个 suds 的模拟客户端。
from suds.client import Client
class AlwaysCallable(object):
"""
Represents a chainable-access object and proxies calls to ClientMock.
"""
name = None
def __init__(self, client_cls):
self._client_cls = client_cls
def __call__(self, *args, **kwargs):
try:
hook = object.__getattribute__(self._client_cls, self.name)
except AttributeError:
pass
else:
return hook(self._client_cls, *args, **kwargs)
def __getattr__(self, item):
new = object.__getattribute__(self, '__class__')(self._client_cls)
new.name = item
return new
class ClientMock(Client):
"""
Abstract mock suds client.
"""
def __init__(self, url, **kwargs):
pass
def __getattr__(self, item):
return AlwaysCallable(self.__class__)
def __unicode__(self):
return 'Client mock'
def __str__(self):
return 'Client mock'
接下来,定义一个具体的 ClientMock。
class UserCredentialsServiceClientMock(ClientMock):
"""
Mock object that implements remote side services.
"""
def GetUserInfo(cls, user_id):
"""
Stub for remote service.
"""
return UserInfo(id=user_id, name='Adam Smith')
现在你可以使用模拟库来伪造一段代码,这段代码使用了 suds.client.Client。
from unittest import TestCase
from mock import patch
from project.api import get_user_credentials
class UserCredentialsClientTestCase(TestCase):
def test_getting_user_credentials(self):
with patch('project.api.Client', new=UserCredentialsServiceClientMock):
self.assertEquals(get_user_credentials(1), 'Adam Smith')
我建议你使用soapUI来创建一个模拟服务。这个工具安装起来非常简单,创建一个WS模拟服务也同样容易。它会从你指定的位置获取WSDL文件,然后根据这个文件的结构来生成请求的格式。如果你需要,它还可以根据WSDL文件的结构创建一个模拟的网络服务。
当你创建新的soapUI项目时,记得选择第三个复选框选项,这样就可以创建模拟的网络服务了。
如果需要xsd模式文件,确保它们在WSDL文件中有正确的引用。
虽然它不使用Python,但如果你只需要一个可以发送请求并获取响应的测试环境,那就足够了。
希望这些信息对你有帮助。
作为一个模拟服务器,我非常推荐使用soapUI(http://www.soapui.org)。
它可以读取一个WSDL文件,然后自动生成服务和服务方法。接下来,你可以定义静态的返回值,或者使用Groovy脚本来设置动态返回值。想了解更多,可以查看这里的文档,里面有关于网络服务模拟的详细说明。
soapUI有免费版和付费的专业版。我使用过免费版,效果非常好。