繁体   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