1
1
import pytest
2
+ import mock as mock_module
2
3
3
4
4
5
class MockFixture (object ):
6
+ """
7
+ Fixture that provides the same interface to functions in the mock module,
8
+ ensuring that they are uninstalled at the end of each test.
9
+ """
10
+
5
11
def __init__ (self ):
6
- self ._patches = []
12
+ self ._patches = [] # list of mock._patch objects
7
13
self .patch = self ._Patcher (self ._patches )
8
14
9
15
def stopall (self ):
16
+ """
17
+ Stop all patchers started by this fixture. Can be safely called multiple
18
+ times.
19
+ """
10
20
for p in self ._patches :
11
21
p .stop ()
12
22
self ._patches [:] = []
13
23
14
24
class _Patcher (object ):
25
+ """
26
+ Object to provide the same interface as mock.patch, mock.patch.object,
27
+ etc. We need this indirection to keep the same API of the mock package.
28
+ """
29
+
15
30
def __init__ (self , patches ):
16
31
self ._patches = patches
17
32
18
- def object (self , * args , ** kwargs ):
19
- import mock
20
-
21
- p = mock .patch .object (* args , ** kwargs )
33
+ def _start_patch (self , mock_func , * args , ** kwargs ):
34
+ """Patches something by calling the given function from the mock
35
+ module, registering the patch to stop it later and returns the
36
+ mock object resulting from the mock call.
37
+ """
38
+ p = mock_func (* args , ** kwargs )
22
39
mocked = p .start ()
23
40
self ._patches .append (p )
24
41
return mocked
25
42
43
+ def object (self , * args , ** kwargs ):
44
+ """API to mock.patch.object"""
45
+ return self ._start_patch (mock_module .patch .object , * args , ** kwargs )
26
46
27
- def multiple (self , * args , ** kwargs ):
28
- import mock
29
47
30
- p = mock . patch . multiple (* args , ** kwargs )
31
- mocked = p . start ()
32
- self ._patches . append ( p )
33
- return mocked
48
+ def multiple (self , * args , ** kwargs ):
49
+ """API to mock.patch.multiple"""
50
+ return self ._start_patch ( mock_module . patch . multiple , * args ,
51
+ ** kwargs )
34
52
35
53
36
54
def __call__ (self , * args , ** kwargs ):
37
- import mock
38
-
39
- p = mock .patch (* args , ** kwargs )
40
- mocked = p .start ()
41
- self ._patches .append (p )
42
- return mocked
55
+ """API to mock.patch"""
56
+ return self ._start_patch (mock_module .patch , * args , ** kwargs )
43
57
44
58
45
59
@pytest .yield_fixture
46
60
def mock ():
61
+ """
62
+ return an object that has the same interface to the `mock` module, but
63
+ takes care of automatically undoing all patches after each test method.
64
+ """
47
65
result = MockFixture ()
48
66
yield result
49
67
result .stopall ()
0 commit comments