Python: invoking a stop invoice for a mock patch class decoder

The Mock documentation describes a simple and elegant way to apply patches to all test methods inside TestCase:

@patch('foo.bar')
@patch('foo.baz')
@patch('foo.quux')
@patch('foo.narf')
class FooTest(TestCase):

    def test_foo(self, bar, baz, quux, narf):
        """ foo """
        self.assertTrue(False) 

However, one of the problems I encountered with this method is that if I want to call stop () on one of the fixes inside one of the testing methods, it seems that I can’t get a link to the patcher object - the only that is passed into the method, this is the layout of objects, in this case bar, baz, quux, narf.

The only way I found to solve this problem is to go to the template described in the Mock docs, where patches are created and run inside the method setUp TestCaseand stop inside the tearDownmethod. This is consistent with my goal, but adds a lot of extra template and not as elegant as the class decor approach.

Is there any other way to solve this problem?

+4
source share
1 answer

1

, foo.narf . foo.narf - - MagicMock. _mock_wraps, mock! , , _narf = foo.narf foo.narf._mock_wraps = _narf.

, , , , (, , " " ). , ( ), _mock_wraps() , .

2

patch() patcher ( ), patchings, . self.test_foo.patchings , , .

start() stop() , patch() , , . .

class unpatch:
    def __init__(self, name, method):
        compare = patch(name)
        self.patcher = next((
            p for p in method.patchings
            if p.target == compare.getter()
            and p.attribute == compare.attribute
        ), None)
        if self.patcher is None:
            raise ValueError(name)

    def __enter__(self):
        self.patcher.__exit__()

    def __exit__(self, *exc_info):
        self.patcher.__enter__()

:

with unpatch('foo.narf', self.test_foo):
    foo.narf()

: .

+5

All Articles