1 # Copyright (c) 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.assertEqual(self.originalObject.foo, self.testObject.foo)
39 self.assertEqual(self.originalObject.bar, self.testObject.bar)
40 self.assertEqual(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.assertEqual('haha', self.testObject.foo)
52 self.assertEqual('hehe', self.testObject.bar)
53 self.assertEqual(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.assertEqual(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.assertEqual(self.testObject.foo, 'BLAH')
84 self.monkeyPatcher.restore()
85 self.assertEqual(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.assertEqual(self.testObject.foo, self.originalObject.foo)
96 self.monkeyPatcher.restore()
97 self.assertEqual(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.assertEqual('foo', result)
113 self.assertEqual([(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.assertEqual(self.originalObject.foo, self.testObject.foo)
142 self.monkeyPatcher.runWithPatches(lambda: None)
143 self.assertEqual(self.originalObject.foo, self.testObject.foo)
146 def test_runWithPatchesRestoresOnException(self):
148 Test runWithPatches restores the original values even when the function
152 self.assertEqual(self.testObject.foo, 'haha')
153 self.assertEqual(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.assertEqual(self.testObject.foo, self.originalObject.foo)
161 self.assertEqual(self.testObject.bar, self.originalObject.bar)