为测试类中的所有测试处理相同的Python异常

时间:2017-05-30 21:15:54

标签: python python-2.7 testing automated-tests

setUp()方法类似,有没有办法在一个地方定义如何为给定TestCase测试类中的所有测试处理某个异常?

我的用例:mock / patch' s assert_any_call的堆栈跟踪只提供了它无法找到的预期调用,但我想添加针对mock的实际调用。每个单元测试都可以将此信息添加到except子句中的堆栈跟踪中,但我希望它在一个地方定义以避免膨胀的代码。

1 个答案:

答案 0 :(得分:0)

正如@Jérôme所指出的,这可以通过创建一个装饰器来包装你的测试来实现(例如https://stackoverflow.com/revisions/43938162/1

以下是我最终使用的代码:

import mock
from unittest import TestCase
from foo.bar import method_that_calls_my_class_method


def _add_mock_context(test_func):
    """This decorator is only meant for use in the MyClass class for help debugging test failures.
    It adds to the stack trace the context of what actual calls were made against the method_mock,
    without bloating the tests with boilerplate code."""
    def test_wrapper(self, *args, **kwargs):
        try:
            test_func(self, *args, **kwargs)
        except AssertionError as e:
            # Append the actual calls (mock's exception only includes expected calls) for debugging
            raise type(e)('{}\n\nActual calls to my_method mock were:\n{}'.format(e.message, self.method_mock.call_args_list))
    return test_wrapper


class TestMyStuff(TestCase):
    def setUp(self):
        class_patch = mock.patch('mine.MyClass', autospec=True)
        self.addCleanup(class_patch.stop)
        class_mock = class_patch.start()
        self.method_mock = class_mock.return_value.my_method

    @_add_mock_context
    def test_my_method(self):
        method_that_calls_my_class_method()
        self.method_mock.assert_any_call(arg1='a', arg2='b')
        self.method_mock.assert_any_call(arg1='c', arg2='d')
        self.method_mock.assert_any_call(arg1='e', arg2='f')
        self.assertEqual(self.method_mock.call_count, 3)