1
# Copyright (c) 2007 Twisted Matrix Laboratories.
2
# See LICENSE for details.
5
Tests for L{twisted.python.monkey}.
8
from twisted.trial import unittest
9
from twisted.python.monkey import MonkeyPatcher
14
self.foo = 'foo value'
15
self.bar = 'bar value'
16
self.baz = 'baz value'
19
class MonkeyPatcherTest(unittest.TestCase):
21
Tests for L{MonkeyPatcher} monkey-patching class.
25
self.testObject = TestObj()
26
self.originalObject = TestObj()
27
self.monkeyPatcher = MonkeyPatcher()
32
A monkey patcher without patches shouldn't change a thing.
34
self.monkeyPatcher.patch()
36
# We can't assert that all state is unchanged, but at least we can
37
# check our test object.
38
self.assertEquals(self.originalObject.foo, self.testObject.foo)
39
self.assertEquals(self.originalObject.bar, self.testObject.bar)
40
self.assertEquals(self.originalObject.baz, self.testObject.baz)
43
def test_constructWithPatches(self):
45
Constructing a L{MonkeyPatcher} with patches should add all of the
46
given patches to the patch list.
48
patcher = MonkeyPatcher((self.testObject, 'foo', 'haha'),
49
(self.testObject, 'bar', 'hehe'))
51
self.assertEquals('haha', self.testObject.foo)
52
self.assertEquals('hehe', self.testObject.bar)
53
self.assertEquals(self.originalObject.baz, self.testObject.baz)
56
def test_patchExisting(self):
58
Patching an attribute that exists sets it to the value defined in the
61
self.monkeyPatcher.addPatch(self.testObject, 'foo', 'haha')
62
self.monkeyPatcher.patch()
63
self.assertEquals(self.testObject.foo, 'haha')
66
def test_patchNonExisting(self):
68
Patching a non-existing attribute fails with an C{AttributeError}.
70
self.monkeyPatcher.addPatch(self.testObject, 'nowhere',
72
self.assertRaises(AttributeError, self.monkeyPatcher.patch)
75
def test_patchAlreadyPatched(self):
77
Adding a patch for an object and attribute that already have a patch
78
overrides the existing patch.
80
self.monkeyPatcher.addPatch(self.testObject, 'foo', 'blah')
81
self.monkeyPatcher.addPatch(self.testObject, 'foo', 'BLAH')
82
self.monkeyPatcher.patch()
83
self.assertEquals(self.testObject.foo, 'BLAH')
84
self.monkeyPatcher.restore()
85
self.assertEquals(self.testObject.foo, self.originalObject.foo)
88
def test_restoreTwiceIsANoOp(self):
90
Restoring an already-restored monkey patch is a no-op.
92
self.monkeyPatcher.addPatch(self.testObject, 'foo', 'blah')
93
self.monkeyPatcher.patch()
94
self.monkeyPatcher.restore()
95
self.assertEquals(self.testObject.foo, self.originalObject.foo)
96
self.monkeyPatcher.restore()
97
self.assertEquals(self.testObject.foo, self.originalObject.foo)
100
def test_runWithPatchesDecoration(self):
102
runWithPatches should run the given callable, passing in all arguments
103
and keyword arguments, and return the return value of the callable.
108
log.append((a, b, c))
111
result = self.monkeyPatcher.runWithPatches(f, 1, 2, c=10)
112
self.assertEquals('foo', result)
113
self.assertEquals([(1, 2, 10)], log)
116
def test_repeatedRunWithPatches(self):
118
We should be able to call the same function with runWithPatches more
119
than once. All patches should apply for each call.
122
return (self.testObject.foo, self.testObject.bar,
125
self.monkeyPatcher.addPatch(self.testObject, 'foo', 'haha')
126
result = self.monkeyPatcher.runWithPatches(f)
128
('haha', self.originalObject.bar, self.originalObject.baz), result)
129
result = self.monkeyPatcher.runWithPatches(f)
131
('haha', self.originalObject.bar, self.originalObject.baz),
135
def test_runWithPatchesRestores(self):
137
C{runWithPatches} should restore the original values after the function
140
self.monkeyPatcher.addPatch(self.testObject, 'foo', 'haha')
141
self.assertEquals(self.originalObject.foo, self.testObject.foo)
142
self.monkeyPatcher.runWithPatches(lambda: None)
143
self.assertEquals(self.originalObject.foo, self.testObject.foo)
146
def test_runWithPatchesRestoresOnException(self):
148
Test runWithPatches restores the original values even when the function
152
self.assertEquals(self.testObject.foo, 'haha')
153
self.assertEquals(self.testObject.bar, 'blahblah')
154
raise RuntimeError, "Something went wrong!"
156
self.monkeyPatcher.addPatch(self.testObject, 'foo', 'haha')
157
self.monkeyPatcher.addPatch(self.testObject, 'bar', 'blahblah')
159
self.assertRaises(RuntimeError, self.monkeyPatcher.runWithPatches, _)
160
self.assertEquals(self.testObject.foo, self.originalObject.foo)
161
self.assertEquals(self.testObject.bar, self.originalObject.bar)