为什么assert_called_with无法通过?

时间:2016-12-06 03:05:12

标签: mocking patch python-2.6

我在设置单元测试时遇到了很多困难。我一直在使用补丁,但它的表现并不像预期的那样。

我的测试功能顶部有一个装饰器: @mock.patch('WarningFactory.WarningAPIUpdate') @mock.patch('WarningFactory.SomethingElse') def test_send_tc_update(self, other_mock, api_mock):

然而,当我尝试做出以下断言时,在我的函数结束时:

api_mock.send_warning.assert_called_with('IDQ20026', 'IDQ20026')

失败

我知道应该通过,因为我跑

print api_mock.mock_calls

[call(u'test_api'), call().send_warning('IDQ20026', 'IDQ20026'), call().send_warning('IDQ24500', 'IDQ24500')]

我可以清楚地看到使用正确的值调用send_warning方法,为什么我的断言失败?

3 个答案:

答案 0 :(得分:4)

现在回想一下问题是assert_called_with只检查最近的呼叫。

  

assert_any_call(* args,** kwargs)¶断言模拟已被调用   指定的参数。

     

如果模拟被调用,则断言传递,不像   assert_called_with()和assert_called_once_with()只传递if   这个电话是最近的一个,而在这种情况下   assert_called_once_with()它也必须是唯一的调用。

文档有点狡猾,因为他们没有在assert_called_with方法下提到这一点。

我最终使用assert_any_call方法进行测试。

答案 1 :(得分:0)

如果user3559247's answer不起作用,则可能是您在尝试模拟嵌套对象,您将需要阅读有关chaining mock calls的信息。就我而言,我想在假设类MyAzureBatchClient中利用Azure Python SDK测试此代码:

def node_counts():
  self.batch_client = azure.batch.batch_service_client.BatchServiceClient(...)
  self.batch_client.account.list_pool_node_counts()
  ...

调用mocked_batch_client.account.list_pool_node_counts.assert_called_with()失败,尽管检查mock_calls属性会显示与您类似的内容:

[call().list_pool_node_counts()]

但是,与mocked_batch_client.return_value.account.list_pool_node_counts.assert_called_with()正确链接时,它可以按预期工作。检查mocked_batch_client.return_value.account.mock_calls时,请注意call.method的存在方式,而不是call().method: [call.list_pool_node_counts()]

答案 2 :(得分:0)

根据您提到的打印输出,语法可能应该是:

api_mock.return_value.send_warning.assert_called_with('IDQ20026', 'IDQ20026')

注意 call()send_warning('IDQ20026', 'IDQ20026')前缀,它与.return_value相关。

但是为什么要这么努力?我写了helper library为我自动生成断言。

只需添加这些行即可为您的案例打印正确的断言:

import mock_autogen.generator
print(mock_autogen.generator.generate_asserts(api_mock))