簡體   English   中英

訪問 python unittest magicmock 返回值

[英]access python unittest magicmock return value

我正在使用帶有 unittest 和 mock 的 python 3.9.2 來修補 class。

我的測試代碼實例化了 class 的 object 並模擬返回 MagicMock object 作為實例。

我的問題是,我可以從我的測試代碼中訪問那個 object 嗎?

我可以在 mock_calls 列表中看到實例化 class 的調用,但找不到訪問從該調用返回的實例的方法。

我需要訪問實例的原因是我的測試代碼將屬性附加到實例而不是調用它的方法。 測試方法調用很容易,但是有沒有直接測試屬性的方法?

經過調查,我發現每次實例化我的 class 時,只有一個 MagicMock 實例被創建並返回。 由於我添加到 class 的屬性,這種行為對我來說並不方便。

我創建了以下測試輔助來支持我的需求。 這不是通用的,但可以適應其他情況。

class MockMyClass():
"""mock multiple MyClass instances
Note - the code under test must add a name attribute to each instance
"""

def __init__(self):
    self.myclass = []

def factory(self, /, *args, **kwargs):
    """return a new instance each time called"""
    new = mock.MagicMock()
    # override __enter__ to enable the with... context manager behaviour
    # for convenience in testing
    new.__enter__ = lambda x: new
    self.myclass.append(new)
    return new

def __getitem__(self, key: str) -> None:
    """emulate a dict by returning the named instance
    use as
    mockmyclass['name'].assert_called_once()
    or
    with mockmyclass['name'] as inst:
        inst.start().assert_called_once()
    """
    # Important - the code under test gives the instance a name
    # attribute and this relies on that attribute so is not
    # general purpose
    wanted = [t for t in self.myclass if t.name == key]
    if not wanted:
        names = [t.name for t in self.myclass]
        raise ValueError(f'no timer {key} in {names}')
    return wanted[0]

class 測試行為(unittest.TestCase):

def setUp(self):
    self.mockmyclass = MockMyClass()
    self.mocked = mock.patch(
        'path-to-my-file.MyClass',
        side_effect=self.mockmyclass.factory,
    )
    self.addCleanup(self.mocked.stop)
    self.mocked = self.mocked.start()

def test_something(self):
    # call code under test
    # then test with
    with self.mockmyclass['name-of-instance'] as inst:
        inst.start.assert_called_once()
        inst.stop.assert_called_once()
    # or test with
    self.mockmyclass['name-of-instance'].start.assert_called_once()

暫無
暫無

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

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