开发者

Creating a mock web service from a WSDL file in Python

We are writing a client for a remote service that exposes SOAP web services and publishes a WSDL definition for those services.

We don't have access to the system during testing, so we'd like to write a mock service. We're using Python for the client, so ideally we'd want to use Python for the mock server, although I suppose it's not strictly necessary.

The dream would be to be able to generate stubs from the WSDL file which we could fill in, and t开发者_StackOverflow中文版hen serve those using Paste Deploy as a WSGI server, although it doesn't have to be Paste Deploy or WSGI so long as it works reliably. The main thing is that we need to be generating the stubs from the "real" WSDL file so that we don't accidentally write a non-compliant mock server.

We're using suds for the client side library, and have looked at soaplib and ZSI. However, the wsgi2py stuff in soaplib says "do not use" at the top and ZSI seems like a lot to swallow. What do people generally use for this kind of thing?

Martin


As a mock server I would really recommend soapUI (http://www.soapui.org).

It takes a WSDL and generates the services and service methods automatically. You can then go on and define static returns or dynamic ones using Groovy scripts. Take a look here for the documentation of web service mocking.

soapUI comes in a free and paid pro version. I have used the free version with great success.


I would recommend you use soapUI for creating a mock service. It's very easy to install. It's just as easy to create a WS mock service. It takes the WSDL file from your desired location, it creates the structure for the requests and if you wish, it also creates the mock web service with the intended structure drawn from the WSDL file. When you create the new soapUI project, select the third checkbox option to create the mock web service.

If xsd schema files are required, make sure they are well referenced from the WSDL file.

It doesn't use python but if all you need is a test environment that you can send requests and get responses, that will be more than enough.

I hope that helps.


You could use this code for creating a suds mock client.

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'

And next define a concrete 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')

Now you could use mock library to spoof a code, that uses 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')
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜