2013-02-05 28 views
4

我正在编写单元测试,我需要模拟一个方法调用,以便在大多数情况下,它表现为方法本身,除非参数获取特殊值“insert into”。这里是一个简化的生产代码:使用模拟库来修补类方法

class CommandServer(object): 
    def __init__(self): 
     self.rowcount = None 
    def runSQL(self, sql): 
     print "Do something useful" 
     self.rowcount=5 
     return self 

class Process(object): 
    def process(self): 
     cs = CommandServer() 
     cs.runSQL("create table tbl1(X VARCHAR2(10))") 
     r = cs.runSQL("insert into tbl1 select * from tbl2") 
     print "Number of rows: %s" % r.rowcount 

p = Process() 
p.process() 

它打印

Do something useful 
Do something useful 
Number of rows: 5 

我可以做一个模拟版本,使用下面的代码自己:

runSQL = CommandServer.runSQL 
def runSQLPatch(self, sql): 
    if sql.lstrip().startswith('insert into'): 
     print "Patched version in use" 
     class res(object): 
      rowcount = -1 
     return res 
    else: 
     return runSQL(self, sql) 
CommandServer.runSQL = runSQLPatch 

p = Process() 
p.process() 

它打印

Do something useful 
Patched version in use 
Number of rows: -1 

我想使用mocklibrary来完成相同的(我相信这是包含在python 3中的库)。我怎样才能做到这一点? (Python 2.6.2)

回答

1

为了清楚起见,它只包含在python 3.3中(我很开心已经学会了,谢谢!)。

否则,您可以使用该模式是

from mock import patch 

with patch.object(CommandServer, 'runSQL') as runSQL: 
    class res(object): 
     rowcount = -1 

    runSQL.return_value = res 

    p = Process() 
    p.process() 

    for c in runSQL.call_list: 
     assert c[1].lstrip().startswith('insert into') is True 

但是,这将覆盖所有的情况下,不只是情况下,你要发送'insert into'。这可能会给你一个暗示在哪里看,但否则,我不认为你正在寻找的是完全可能的模拟。