2010-09-16 146 views
4

我試圖針對我在Django中運行鍼對第三方API運行的代碼構建一些單元測試。具體來說,我將一些用戶數據與MailChimp同步,並使用實現MailChimp API的庫。如何在執行Django單元測試時禁用第三方API?

我有一個自定義類MailChimpAPI,它本質上充當我正在使用的Python庫的一個薄包裝器。下面是一些代碼相關部分:

class MailChimpAPI(object): 
    """ 
    A wrapper for implementing business logic and exception handling around 
    the PyChimp API 
    """ 
    ... 

    def __init__(self, api_key, primary_list_id, merge_keys, use_secure=True, timeout=None): 
     ... 

     # setup api 
     self.api_key = api_key 
     self.api = PyChimp(self.api_key) 

     ... 

    ... 


    def _call(self, method_name, args=[], kwargs={}): 
     """Calls the PyChimp API directly""" 
     result = getattr(self.api, method_name)(*args, **kwargs) 
     if self.api.errorCode: 
      self._raise_mailchimp_exception() 
     else: 
      return result 

    ... 

我剪掉了。(...)大部分實現業務邏輯等的代碼,但這裏的顯着的方面之一是,我的api屬性設置爲PyChimp(第三方庫)的實例在__init__()中,並且對該庫的所有實際調用均在_call()函數中進行。

我對單元測試有點新,所以我很難找出解決這個問題的最佳方法。我想到的一個想法是在我的類之外實例化PyChimp庫並將其傳遞給構造函數。另一個想法是在測試這個我可以嘲笑_call方法,以便它不擊中實際的庫。

我有的第一個問題是,顯然,我不想對實際的API執行任何測試代碼。所以我試圖弄清楚「存根」或「模擬」API的最佳方式,以便在測試期間對其進行的調用實際上不會執行。理想情況下,我希望在Django測試套件中運行的所有測試都具有該模擬API。例如,我正在探索在通過post_save信號創建用戶帳戶時將用戶同步到MailChimp的可能性。出於這個原因,我顯然不希望在Django Authentication應用程序中運行的測試也觸發實際的API。

我希望Django有一些全局設置/拆卸掛鉤或信號,我可以使用,但似乎沒有任何東西。

有沒有人有任何建議,以便在測試過程中如何完全替換一個「活」API與假裝?或者我是否完全錯誤?

我非常有信心我可以破解我的解決方案,但如果有人願意分享一些關於「最佳」方式來處理這種事情的智慧,那將是非常好的。

回答

1

最好的解決方法是按照你的建議,創建api對象並將其傳遞給構造函數。這將允許您輕鬆地替換api類進行測試。

您可以創建一個MockPyChimp類,它具有與實際PyChimp api相同的方法。通過這種方式,您可以輕鬆地在測試中重複使用相同的模擬類。

我不太熟悉python/django單元測試能夠建議任何特定的庫來協助這個,但我會假設存在某種模擬庫或類似的東西。

+0

是的,這是有道理的,我可以看到如何測試這個類本身。我想現在讓我感到困惑的可能是更多的Django。我的應用程序中有其他代碼,最終觸及這個類(因此也是API),所以我試圖弄清楚如何全局模擬API,而不僅僅是當我測試這個特定的類時。 – jsdalton 2010-09-16 20:32:15

+0

+1:Python很少需要花哨的模擬庫。鴨子打字意味着您可以構建任何符合測試要求的最小API的舊類。在Python中編寫模擬對象通常很簡單。 – 2010-09-16 20:33:16

+1

@jsdalton如果其他測試使用這個類,你應該考慮在其他測試中嘲笑這個類。我之所以提出一個模擬圖書館的原因,即使鴨子打字是因爲如果一個圖書館可以在一個班輪中創建一個虛擬文件,而不必編寫整個班級定義,這在我的書籍中是很好的:) – 2010-09-17 05:39:10

0

那麼在Python中「模擬」函數調用的最好方法是使用mock庫。另外,如果你使用nose作爲你的單元測試框架,那麼值得考慮的插件是nose-blockage,它確保如果你的測試沒有正確地模擬出所有東西,就不會有API調用通過。

相關問題