Consoles
 

Posts Tagged ‘urllib2’

Mocking HTTP request and response with Python and Mox

by David Czarnecki, October 1st, 2009 at 09:55am - No Comments »
Tagged As: , , , , ,
Posted in: Engineering, Python, Uncategorized

I recently started integrating with some web services in Python and wanted to be able to test all the requests and responses with valid and invalid data. However, I need to be able to do this without actually hitting the web service when testing. And of course I don’t want to change my web service code to conditionally do things if running in a test environment. Enter mocking and Mox.

One of our engineers, Tim, has written an excellent post on his adventures as a Ruby programmer getting up to speed on testing and mocking in Python using Mox. You should read it.

Back to my issue with mocking the HTTP request and response.

Here is what I came up with. I first created a MockResponse class that adds a read() method to the string class.

</code>

class MockResponse(str):
'''
Mock response class with a method called read which will be used similar to the response from an HTTP request to a URL
'''
def read(self):
return self

And here is a test in which I mock out the request and response for the urllib2.OpenerDirector.open method. I don't so much care what the request string is passed to the open call, so I use IgnoreArg(). And I return the XML that would be returned by the actual web service to indicate the username and/or password were incorrect.


def test_logging_in_to_network_with_bad_username_and_password(self):
my_network_service = MyNetworkService('foo', 'bar')
self.mock(urllib2.OpenerDirector, 'open')
urllib2.OpenerDirector.open(mox.IgnoreArg()).AndReturn(MockResponse('''
< ?xml version="1.0" encoding="UTF-8"?>
<login>
<status>
<id>30000</id>
<message>ACCT_LOGIN_FAILED</message>
</status>
<accountid>7</accountid>
</login>
'''))
self.replay_all()

self.assertEqual(False, my_network_service.login())
self.mox.UnsetStubs()
self.mox.VerifyAll()

If there's a better way, I'd love to hear your suggestions.