TotT Better Stubbing in Python
So you've learned all about method stubs, mock objects, and fakes. You might be tempted to stub out slow or I/O-dependent built-ins. For example: def Foo(path):
if os.path.exists(path):
return DoSomething()
else:
return DoSomethingElse()
def testFoo(self): # Somewhere in your unit test class
old_exists = os.path.exists
try:
os.path.exists = lambda x: True
self.assertEqual(Foo('bar'), something)
os.path.exists = lambda x: False
self.assertEqual(Foo('bar'), something_else)
finally:
# Remember to clean-up after yourself!
os.path.exists = old_exists
Congratulations, you just achieved 100% coverage! Unfortunately, you might find that this test fails in strange ways. For example, given the following DoSomethingElse which checks the existence of a different file: Foo will now throw an exception in its second invocation because os.path.exists returns False so the assertion fails.def DoSomethingElse(): assert os.path.exists(some_other_file) return some_other_file
You could avoid this problem by stubbing or mocking out DoSomethingElse, but the task might be daunting in a real-life situation. Instead, it is safer and faster to parameterize the built-in:
Remember to download this episode of Testing on the Toilet, print it, and flyer your office.def Foo(path, path_checker=os.path.exists): if path_checker(path): return DoSomething() else: return DoSomethingElse() def testFoo(self): self.assertEqual(Foo('bar', lambda x: True), something) self.assertEqual(Foo('bar', lambda x: False), something_else)
No comments:
Post a Comment