[Python] 在 pytest 裡面 monkey patch staticmethod

[Python] 在 pytest 裡面 monkey patch staticmethod

今天在用 pytest 寫 unit-testing 的時候,遇到一個問題:

有個 class 的 staticmethod 原本是要去讀取資料庫的,

不過想在 unit-testing 裡面,讓它固定傳回一個值 (所謂的 monkey patch)…

 

這個 staticmethod 定義像是這樣:

class DBM(object):
@staticmethod
def foo():
return "data from db"
def process():
return "Processed " + DBM.foo()
print func_to_be_tested()

 

平常呼叫 process() 的時候,它會去呼叫 DBM.foo() 讀取 DB,

再傳回處理後的結果~

但在 unit-testing 裡面,我想要它固定傳回 “fake data” 這個字串,

於是我試著這麼寫:

def test_process():
DBM.foo = lambda: "fake data"
assert process() == "Processed fake data"

 

可是這麼一跑的時候,就出現了 unbound method 的錯誤:

    def process():
>       return "Processed " + DBM.foo()
E       TypeError: unbound method <lambda>() must be called with DBM instance as first argument (got nothing instead)

 

嗯… 看起來是 DBM.foo 原本是個 staticmethod,

直接指定一個普通的 function 給它是不行的…

 

查了一下,stackoverflow: How to monkeypatch a static method? 這裡有解答了,

原來只要用 staticmethod() 把函式包裝一下就可以了~

所以測試程式改成下面這樣,就 OK 囉:

def test_process():
DBM.foo = staticmethod(lambda: "fake data")
assert process() == "Processed fake data"

 

(本頁面已被瀏覽過 420 次)

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *

這個網站採用 Akismet 服務減少垃圾留言。進一步了解 Akismet 如何處理網站訪客的留言資料