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

为测试类中的所有测试处理相同的Python异常,python,python-2.7,testing,automated-tests,Python,Python 2.7,Testing,Automated Tests,与setUp()方法类似,是否有一种方法可以在一个地方定义如何为给定的TestCase测试类中的所有测试处理特定异常 我的用例:mock/patch的assert\u any\u调用的堆栈跟踪只给出它找不到的预期调用,但我想针对mock添加实际调用。每个单元测试都可以在except子句中将此信息添加到堆栈跟踪中,但我希望将其定义在一个位置以避免代码膨胀。正如@Jérôme所指出的,这可以通过创建一个装饰器来包装测试来实现(例如:) 以下是我最终使用的代码: import mock from un

setUp()
方法类似,是否有一种方法可以在一个地方定义如何为给定的
TestCase
测试类中的所有测试处理特定异常


我的用例:mock/patch的
assert\u any\u调用
的堆栈跟踪只给出它找不到的预期调用,但我想针对mock添加实际调用。每个单元测试都可以在except子句中将此信息添加到堆栈跟踪中,但我希望将其定义在一个位置以避免代码膨胀。

正如@Jérôme所指出的,这可以通过创建一个装饰器来包装测试来实现(例如:)

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

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)

正如@Jérôme所指出的,这可以通过创建一个装饰器来包装测试来实现(例如

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

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)

这有帮助吗:?你的测试是什么runner@wim我的试跑者是nose@J是的,谢谢你!我现在就试试这个有帮助吗:?你的测试是什么runner@wim我的试跑者是nose@J是的,谢谢你!我现在就试试这个