Reputation: 26101
I have code that looks like this:
import xmlrpclib
class Base(object):
def __init__(self, server):
self.conn = xmlrpclib.ServerProxy(server)
def foo(self):
return self.conn.do_something()
class Derived(Base):
def foo(self):
if Base.foo():
return self.conn.do_something_else()
How should I use mocking to test the behavior of the Derived
class? I don't want to assume that whatever the XML-RPC connection talks to will actually exist, but I feel like mocking the xmlrpclib
module requires too much knowledge of the implementation of the Base
class (which I have other tests for).
Or, I guess, should I even use mocking to test this? If not, how would you test it?
Upvotes: 4
Views: 1934
Reputation: 30943
With some trivial refactoring (call to do_something_else
is extracted), you can test Derived.foo
logic without needing to "know" about XMLRPC.
import xmlrpclib
class Base(object):
def __init__(self, server):
self.conn = xmlrpclib.ServerProxy(server)
def foo(self):
return self.conn.do_something()
class Derived(Base):
def foo(self):
if Base.foo(self):
return self._bar()
def _bar(self):
# moved to its own method so that you
# you can stub it out to avoid any XMLRPCs
# actually taking place.
return self.conn.do_something_else()
import mox
d = Derived('http://deep-thought/unanswered/tagged/life+universe+everything')
m = mox.Mox()
m.StubOutWithMock(Base, 'foo')
m.StubOutWithMock(d, '_bar')
Base.foo(d).AndReturn(True)
d._bar() # Will be called becase Boo.foo returns True.
m.ReplayAll()
d.foo()
m.UnsetStubs()
m.VerifyAll()
Alternatively or even preferably, you may extract the call to do_something_else
into bar
method on Base
. Which makes sense, if we agree that Base
encapsulates all your XMLRPC actions.
The example uses pymox mocking library, but the gist of it stays the same regardless of your mocking style.
Upvotes: 3
Reputation: 14121
You could create a fake ServerProxy class, and substitute that for testing.
Something like this:
class FakeServerProxy(object):
def __init__(self, server):
self.server = server
def do_something(self):
pass
def do_something_else(self):
pass
def test_derived():
xmlrpclib.ServerProxy = FakeServerProxy
derived = Derived(None)
derived.foo()
Upvotes: 4