2016-09-17 60 views
3

封裝結構:如何在獨立的命名空間中模擬類?

pqr/pq.py 
test.py 

pqr/pq.py有以下結構

凡LMN在全球範圍內安裝了PIP模塊

結構pq.py

from lmn import Lm 

class Ab(): 

    def __init__(self): 
     self.lm = Lm() 

    def echo(self, msg): 
     print msg 

test.py具有以下結構

from pqr.pq import Ab 

如何在這裏模擬Lm()類以測試Ab類中的所有方法?

+1

Python支持Monkey-Patching。你可以簡單地調用'pqr.pq.Lm = your_mockup','Ab'將使用'your_mockup'而不是原來的'Lm'。 (這會回答你的問題,但它可能不是最好的測試模式,考慮修改'Ab'的構造函數以允許通過替代的'Lm'實現。) – Phillip

+0

@Phillip感謝您的回答,但我沒有完全得到它,你能給我一個工作代碼片段,我是測試框架的新手。 – Sanket

回答

4

Lm從何而來並不重要。您將Lm導入pqr.pq命名空間作爲全局那裏,因此您只能在那裏和其他地方替換該名稱。這是因爲Ab.__init__方法會在它自己的模塊中「本地」尋找它。

因此,使用mock library所有你需要做的是打補丁名稱pqr.pq.Lm

import mock 
from pqr.pq import Ab 

with mock.patch('pqr.pq.Lm') as mock_lm: 
    # within this block, `Lm` in the `pqr.pq` namespace has been replaced 
    # by a mock object 
    test_instance = Ab() 
    # assert that the patch succeeded; .return_value is used because 
    # Ab.__init__ *calls* Lm() 
    assert test_instance.lm is mock_lm.return_value 

另見mock文檔的Where to patch section

0

爲了測試,您可以使用mock模塊(新版python 3中的標準版,可從pypi下載舊版本)來創建「假」類。在模擬庫上有一篇很棒的文章解釋瞭如何做到這一點,我將鏈接here,這對我有很大的幫助。你會希望你的test.py文件看起來像下面的代碼。

from pqr import pq 
import mock 

class TestLm(unittest.Testcase): 

    @mock.patch(pq.LM) 
    def test_lm(self, mock_lm): 
     my_ab = pq.AB() 
     my_ab.echo() 

使用mock模塊,你可以簡單地通過「修補」它上面的測試方法的裝飾器創建一個模塊/類,你可以使用方法進行測試,的模擬版本。這會用MagicMock對象替換指定模塊/類的原始版本,然後將其作爲第二個參數傳遞給測試方法。這個MagicMock並沒有實際執行Lm的任何功能,但可以讓你做出關於它應該如何工作的斷言。如果需要,您可以稍後覆蓋功能。但是,這有一個問題,我在相關指南中解釋了這一點。您需要確保從使用該模塊的模塊導入Lm,而不是以傳統方式導入。對於導入,Python會創建特定於它們所導入模塊的模塊對象,因此您需要模擬pq模塊中特定的Lm對象以測試其功能。該庫首先使用起來有點複雜,並且包含的​​信息遠遠多於適合覆蓋單個StackOverflow答案的信息,因此我建議您進行一些閱讀。

mock模塊的文檔可以找到here。 下載Python 2.7版本可以找到here

我自己對mock庫相當陌生,所以隨時糾正我,如果我錯了!

編輯:在看到Martijn的回答後,我意識到我在my_ab構造函數中忘記了括號!

相關問題