使用mocking在Python中测试派生类

时间:2009-01-05 07:16:35

标签: python mocking

我的代码如下:

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()

我应该如何使用模拟来测试Derived类的行为?我不想假设XML-RPC连接的任何内容实际存在,但我觉得嘲笑xmlrpclib模块需要太多的Base类的实现知识(我有其他测试)。

或者,我想,我是否应该使用模拟来测试这个?如果没有,你会如何测试它?

2 个答案:

答案 0 :(得分:4)

您可以创建一个假的ServerProxy类,并将其替换为测试。

这样的事情:

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()

答案 1 :(得分:3)

通过一些简单的重构(提取对do_something_else的调用),您可以测试Derived.foo逻辑而无需“了解”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()

或者甚至优选地,您可以在do_something_else上将bar的调用解压缩为Base方法。如果我们同意Base封装所有XMLRPC操作,那么这是有道理的。

该示例使用pymox模拟库,但无论您的模拟风格如何,它的要点都保持不变。