簡體   English   中英

如何在python單元測試中覆蓋(而非修補)單個方法

[英]How to override (not patch) a single method in a python unit test

我已經搜索了幾個小時。 甚至找不到試圖這樣做的人。

我相信我必須重寫類實例中的單個方法。 不是patch(return_value=) 我需要使所討論的方法做一些涉及self事情。

我會盡力分解。 隨意地改寫並包括我嘗試過的許多方法之一,這是行不通的...

class SetupClass(object):
    def set_some_stuff(self):
        data_list = functon_cannot_be_run_on_test_platform()
        self.something = data_list[0]
        self.something_else = data_list[1]

class UUT(object):
    self.config = SetupClass()
    assert self.config.something == 'foo'

class UnitTests(TestCase):

    @patch('SetupClass')
    def test_UUT(self, mock1):

        def WedgeClass(SetupClass):
            def set_some_stuff(self):
                self.something = 'foo'
                pass # I'm a Python newbie, in too deep

        wedge_class = WedgeClass()
        mock1.return_value = wedge_class # doesn't work. context errors

        uut = UUT() # <-- would crash here, because assert above

假設我無法對UUTSetupClass進行更改。

測試甚至無法啟動,因為斷言將由於SetupClass.functon_cannot_be_run_on_test_platform()而失敗。 請注意 ,由於原因僅嘲笑SetupClass.functon_cannot_be_run_on_test_platform並不能解決問題。

在ATM上,我認為避免這種混亂的唯一方法是以某種方式覆蓋SetupClass.set_some_stuff 我不能簡單地模擬整個類,因為UUT非常依賴於其其他功能。 我需要一切都按原樣工作,除了這個方法之外我還需要該方法能夠在與最初意圖相同的上下文中self訪問。

我嘗試了各種涉及子類化和模擬.return_value等的事情。我寧願不記得引起的痛苦。 :p

我的王國首先是測試驅動的代碼! 此代碼包含一些相互依賴的卷積。 :-/

除了示例代碼中的多個錯誤外,我還在咖啡館里寫下了自己的頭……

問題是(主要是)我使用return_value而不是side_effect將修補的類替換為自己的子類。

現在,我可能需要更清楚地set_some_stuff ,我的需要是在被測單元(UUT)中的類中重寫單個方法set_some_stuffset_some_stuff該類。

該方法發出多個“ self.foo = bar”語句,出於測試目的,我想對其進行更改。 因此,僅嘲笑該方法的(未使用的)返回值是不夠的……並且patch.object似乎丟失了類上下文,“'自身'未知”等。

最后 ,這是工作代碼,執行我需要做的...

import unittest
import mock

class SetupClass(object):
    def set_some_stuff(self):
        data_list = ['data not available', 'on test_platform'] # CRASH!
        self.something = data_list[0]
        self.something_else = data_list[1]

class UUT:
    def __init__(self):
        self.config = SetupClass()
        self.config.set_some_stuff()
        assert self.config.something == 'foo' # <-- used to crash before here ...
        self.got_here = True # ... but now the override method from
                             # WedgeClass is being used! :=)

"""
Subclass the original class, overriding just the method in question.  Then set
the subclass as the side_effect of the patched original, effectively replacing it.
"""
class WedgeClass(SetupClass):
    def set_some_stuff(self):
        self.something = 'foo'
        pass # I'm a Python newbie, in too deep

class UnitTests(unittest.TestCase):

    @mock.patch(__module__+'.SetupClass')
    def test_UUT(self, mock1):
        wedge_class = WedgeClass()
        mock1.side_effect = WedgeClass # <--- Ureka! 'side_effect' not 'return_value' was the ley!

        uut = UUT()
        self.assertTrue(uut.got_here)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM