launchpad-dev team mailing list archive
-
launchpad-dev team
-
Mailing list archive
-
Message #02616
Writing stubs made easy
Greetings fellow hackers,
ever had to do this in test code?
class FakeClass(ClassThatIWantToTest):
"""Version of ClassThatIWantToTest mocked up for testing."""
def _getTime(self):
"""Faking this so the test gets predictable timestamps."""
return datetime.datetime(2010, 02, 14)
Or this?
class MockSlave:
"""Pretend build-farm slave for testing.
Can't invoke a real build-farm slave from the test suite.
"""
run_has_been_called = False
def run(self):
"""Pretend to run."""
self.run_has_been_called = True
Or this?
class FakeTalkToServer(RealTalkToServer):
def talk(self):
"""Simulate protocol failure for testing."""
raise HttpException("Bet you can't catch this!")
I got tired of doing that, so I just landed a branch that makes it all a
bit easier. In lp.testing.fakemethod you'll find a new class
FakeMethod. Objects of this type are stub functions/methods. (But I
didn't call them that so we can discuss them without making Stuart's IRC
client go off :).
A FakeMethod can take the place of any function or method, and:
- Return a constant value.
- Raise an exception instead.
- Tell you how many times it's been invoked.
The tests you needed those fake classes for are now much shorter:
objectiwanttotest._getTime = FakeMethod(
result=datetime.datetime(2010, 02, 14))
or
slave.run = FakeMethod()
do_stuff_with(slave)
# The slave has been run exactly once.
self.assertEqual(1, slave.run.call_count)
or
realtalktoserver.talk = FakeMethod(failure=HttpException(
"Bet you can't catch this!"))
respectively. It saves time writing tests, but also lets your test get
to parts it couldn't normally reach because you can mock up so many
things so quickly. Plus you can unit-test more classes in fast tests
using fewer layers, with all the complex work ripped out and exercised
only in integration tests.
An ancestor of this class allowed me to write unit tests for our failing
EC2 scripts a few months back, and this time I hit a second big use-case
with the buildfarm work. Hope you enjoy it as I do!
Jeroen
Follow ups