我有一個昂貴的__init__
函數的類。我不想從測試中調用這個函數。避免執行模擬類的__init__
對於這個例子的目的,我做了一個類,在__init__
引發了一個異常:
class ClassWithComplexInit(object):
def __init__(self):
raise Exception("COMPLEX!")
def get_value(self):
return 'My value'
我有構造的ClassWithComplexInit
一個實例,並使用它的功能的第二類。
class SystemUnderTest(object):
def my_func(self):
foo = ClassWithComplexInit()
return foo.get_value()
我想寫一些單元測試圍繞SystemUnderTest#my_func()
。我遇到的問題是無論我如何模擬ClassWithComplexInit
,__init__
函數總是被執行並引發異常。
class TestCaseWithoutSetUp(unittest.TestCase):
@mock.patch('mypackage.ClassWithComplexInit.get_value', return_value='test value')
def test_with_patched_function(self, mockFunction):
sut = SystemUnderTest()
result = sut.my_func() # fails, executes ClassWithComplexInit.__init__()
self.assertEqual('test value', result)
@mock.patch('mypackage.ClassWithComplexInit')
def test_with_patched_class(self, mockClass):
mockClass.get_value.return_value = 'test value'
sut = SystemUnderTest()
result = sut.my_func() # seems to not execute ClassWithComplexInit.__init__()
self.assertEqual('test value', result) # still fails
# AssertionError: 'test value' != <MagicMock name='ClassWithComplexInit().get_value()' id='4436402576'>
上面的第二種方法是我從this similar Q&A得到的,但它也沒有工作。它似乎不運行__init__
函數,但我的斷言失敗,因爲結果最終是一個模擬實例,而不是我的價值。
我也試圖在setUp
功能配置patch
例如,使用start
和stop
功能the docs suggest。
class TestCaseWithSetUp(unittest.TestCase):
def setUp(self):
self.mockClass = mock.MagicMock()
self.mockClass.get_value.return_value = 'test value'
patcher = mock.patch('mypackage.ClassWithComplexInit', self.mockClass)
patcher.start()
self.addCleanup(patcher.stop)
def test_my_func(self):
sut = SystemUnderTest()
result = sut.my_func() # seems to not execute ClassWithComplexInit.__init__()
self.assertEqual('test value', result) # still fails
# AssertionError: 'test value' != <MagicMock name='mock().get_value()' id='4554658128'>
這也似乎在迴避我__init__
功能,但我爲get_value.return_value
設置的值不被尊重和get_value()
仍返回MagicMock
實例。
我該如何模擬一個複雜的__init__
類,該類是由我的測試代碼實例化的?理想情況下,我希望有一個解決方案適用於TestCase類中的許多單元測試(例如,不需要每次測試都需要patch
)。
我正在使用Python版本2.7.6
。
如何讓'ClassWithComplexInit'可用於您的測試腳本? '從mypackage導入ClassWithComplexInit'或其他東西? – chepner 2014-11-05 21:17:48
@chepner我的測試腳本甚至沒有導入'ClassWithComplexInit'。我從我的真實代碼切換了一堆代碼在SO上發佈,並搞砸了包引用,我意識到引用是錯誤的。你在回答中解決了這個問題,謝謝! – 2014-11-05 22:14:34