2011-09-06 34 views
2

我有一些特殊情況需要在django中測試。我試圖通過編寫我自己的測試用例來擴展現有的django測試。這是我目前正在做的事情。如何用自己的方法從外部庫中增加一個類?

from django.tests import TestCase 

# define my own method as a function 
def assertOptionsEqual(self, first, second): 
    # logic here 
    pass 

# Attach the method to the TestCase class. This feels inelegant! 
TestCase.assertOptionsEqual = assertOptionsEqual 

# tests go here 
class KnownGoodInputs(TestCase): 
    def test_good_options(self): 
     self.assertOptionsEqual(...) 

雖然其工作原理,限定的方法與self作爲第一個參數的函數,然後將其附連到TestCase感覺不雅。用我自己的方法是否有更好的方法來增強TestCase類?我能做到這一點...

class MyTestCase(TestCase): 
    def assertOptionsEqual(self, first, second): 
     ... 

,並使用MyTestCase所有測試,但不知道是否有一個更好的選擇。謝謝!

+0

怎麼樣強迫t子類化和使用另一個方法名稱? – fabrizioM

回答

1

我想你已經涵蓋了這兩個選項。你可以是子類或monkeypatch。通常,monkeypatching,實際上在運行時改變第三方類是不受歡迎的,但取決於你需要做出什麼樣的改變,這可能是解決錯誤的唯一方法,或者確保每次使用該類時都有你的新方法。

由於使用您的方法的唯一測試將是您的測試monkeypatching是不必要的,並且子類TestCase是相當合理的。通常,當您需要增加現有類的方法時,您會使用monkeypatching。例如,如果你在你現有的測試用例想調用TestCase.assertEqual與邏輯被擴充以比較Option對象,你可以猴補丁TestCase.assertEqual包括您的定製邏輯加上做一些喜歡它的正常的邏輯:

originalAssertEqual = TestCase.assertEqual 
def newAssertEqual(self, first, second): 
    result = originalAssertEqual(first, second) 
    if isinstance(first, Option) and isinstance(second, Option): 
     # do your custom comparison 
    return result 
TestCase.assertEqual = newAssertEqual 

然而,似乎至少在這個例子中,子類和monkeypatches都是不必要的。

假設問題是即使Option實例相同,調用self.assertEqual(firstOptions, secondOptions)失敗,也不需要編寫新的assertOptionsEqual方法。您可能只需要您的Option對象來正確定義__eq__

所以假設你有:

class KnownGoodInputs(TestCase): 
    def test_good_options(self): 
     first, second = systemUnderTestGetOptions(...) 
     self.assertOptionsEqual(first, second) 

什麼是first以上second類?

對於所有Python內置類型assertEqual都應該有效。對於定製Option類只是做這樣的事情:

類選項(對象): DEF 初始化(個體經營): use_foo =假 use_bar =真

def __eq__(self, other): 
    if (self.use_foo == other.use_foo and 
     self.use_bar == other.use_bar): 
     return True 
    return False 

然後假設firstsecondOption的實例,你可以這樣寫你的測試:

class KnownGoodInputs(TestCase): 
    def test_good_options(self): 
     first, second = systemUnderTestGetOptions(...) 
     self.assertEqual(first, second) 
+1

感謝您的詳細解答!嘗試定義'__eq__'是首選。但是,被比較的對象是Django本機對象(Aggregates,QuerySets等))沒有定義'__eq__'。所以我要麼必須爲某些本地Django對象修飾一個'__eq__'方法或者修改TestCases。所以我想我試圖選擇兩個邪惡中較小的一個! ;) –

相關問題