模拟注入类方法

时间:2017-11-17 02:27:14

标签: python unit-testing dependency-injection mocking

我有一个包含Resource类实例的Gateway类。我已经完成了对Resource的单元测试,为了简化测试,Resource在初始化时作为依赖注入Gateway:

class Gateway:

  def __init__(self, resource):
    self._resource = resource(Master)

  def list_things(self):
    return self._resource.list_resource()

现在,我想为Gateway编写单元测试,以验证调用resource.list_resource()后是否gateway.list_things()被调用。我最好的尝试不起作用:

class TestGateway(unittest.TestCase):

    def test_list_things(self):
        mock_resource = Mock()
        g = modbus.gateway.Gateway(mock_resource)
        g.list_things()
        mock_resource.list_resource.assert_called_once()

结果:

AssertionError: Expected 'list_resource' to have been called once. Called 0 times.

我错过了什么?

1 个答案:

答案 0 :(得分:1)

在您为测试用例传入mock_resource的{​​{1}}的实际用例中,Gateway中的构造函数实际上进一步调用Gateway参数作为构造函数,因此测试所期望的实际上是模拟对类方法的调用的检查,而不是resource的实例方法。只需使用最少数量的语句即可使用以下方法进行演示:

mock_resource

请注意,我已在>>> mock_resource = Mock() >>> self_resource = mock_resource('Master') # emulate Gateway.__init__ >>> self_resource.list_resource() # emulate Gateway.list_things <Mock name='mock().list_resource()' id='140441464498496'> >>> mock_resource.list_resource.assert_called_once() # test_list_things Traceback (most recent call last): File "<stdin>", line 1, in <module> File "/usr/lib/python3.6/unittest/mock.py", line 795, in assert_called_once raise AssertionError(msg) AssertionError: Expected 'list_resource' to have been called once. Called 0 times. >>> self_resource.list_resource.assert_called_once() # test the _actual_ call >>> 的构造函数中指定了self_resource来模拟self._resource = resource(Master)语句,并且测试与实际执行的内容之间的不匹配现在应该是显而易见的。< / p>

要解决这个问题,测试应该像这样检查呼叫:

Resource