Python - assert_called_with在传递AttributeError作为参数时

3

我正在尝试对一个名为 TargetException 的自定义异常进行单元测试。

这个异常的参数之一本身就是一个异常。

以下是我测试中相关的部分:

mock_exception.assert_called_once_with(
    id,
    AttributeError('invalidAttribute',)
)

以下是测试失败的信息:

  File "/usr/local/lib/python2.7/site-packages/mock/mock.py", line 948, in assert_called_once_with
    return self.assert_called_with(*args, **kwargs)
  File "/usr/local/lib/python2.7/site-packages/mock/mock.py", line 937, in assert_called_with
    six.raise_from(AssertionError(_error_message(cause)), cause)
  File "/usr/local/lib/python2.7/site-packages/six.py", line 718, in raise_from
    raise value
AssertionError: Expected call: TargetException(<testrow.TestRow object at 0x7fa2611e7050>, AttributeError('invalidAttribute',))
Actual call: TargetException(<testrow.TestRow object at 0x7fa2611e7050>, AttributeError('invalidAttribute',))

在“期望调用”和“实际调用”中,出现了相同的参数--至少在我看来是这样的。
我需要以不同的方式传递AttributeError来解决错误吗?

我认为你应该使用assertRaises来测试是否引发了异常(https://docs.python.org/3/library/unittest.html#unittest.TestCase.assertRaises),而不是普通的called_once断言。 - D-E-N
2个回答

2
问题在于您比较了包含异常的实例。由于测试函数中创建的AttributeError实例和用于比较的实例不同,因此断言失败。
相反,您可以分别测试调用的参数以确保它们是正确的类型。
@mock.patch('yourmodule.TargetException')
def test_exception(mock_exception):
    # call the tested function
    ...
    mock_exception.assert_called_once()
    assert len(mock_exception.call_args[0]) == 2  # shall be called with 2 positional args
    arg1 = mock_exception.call_args[0][0]  # first argument
    assert isinstance(arg1, testrow.TestRow)  # type of the first arg
    ... # more tests for arg1

    arg2 = mock_exception.call_args[0][1]  # second argument
    assert isinstance(arg2, AttributeError)  # type of the second arg
    assert str(arg2) == 'invalidAttribute'  # string value of the AttributeError

例如,您需要分别测试类和相关参数的值。 使用assert_called_with仅适用于POD,或者如果您已经知道所调用的实例(例如如果它是单例或已知模拟)。

0

在MrBean Bremen的答案基础上进行扩展。

另一种解决方法是将异常保存在变量中,并检查该变量:

ex = AttributeError('invalidAttribute',)
...
def foo():
    raise ex
...
mock_exception.assert_called_once_with(
    id,
    ex
)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接