2013-02-05 26 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'。這可能會給你一個暗示在哪裏看,但否則,我不認爲你正在尋找的是完全可能的模擬。