Created
August 10, 2011 20:13
-
-
Save keturn/1138086 to your computer and use it in GitHub Desktop.
asserting a function is a composite function
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
"""An example for discussion on "Fixing Untestable Code Sequences" | |
http://arlobelshee.com/post/mock-free-example-part-3-fixing-untestable-code-sequences | |
""" | |
from twisted.trial.unittest import TestCase | |
class ParserDoodle(object): | |
def parseCharacterIntoCards(self): | |
for powerElement in self.findAllPowers(): | |
yield self.createPowerCard(powerElement) | |
def createPowerCard(self, powerElement): | |
localInfo = self.toPowerInfo(powerElement) | |
powerDetails = self.getOnlineInfoForPower(localInfo) | |
powerInfo = self.cleanTheResponse(powerDetails) | |
viewModel = self.createViewModel(powerInfo) | |
return viewModel | |
def findAllPowers(self): | |
return [] | |
def toPowerInfo(self, powerElement): | |
return 'W' | |
def getOnlineInfoForPower(self, localInfo): | |
return 'X' | |
def cleanTheResponse(self, powerDetails): | |
return 'Y' | |
def createViewModel(self, powerInfo): | |
return 'Z' | |
class TestParserDoodle(TestCase): | |
def fakeComponent(self, expected, result): | |
def stub(x): | |
self.assertIdentical(expected, x) | |
return result | |
return stub | |
def assertIsComposite(self, func, components): | |
"""Assert the given function is a composite of the specified | |
functions. | |
:param func: f(x) -> x | |
:type func: callable | |
:param components: list of composite functions, specified as a tuple | |
of parent object and attribute name. | |
:type components: [object, str] | |
:return: None | |
""" | |
assert components | |
initialInput = object() | |
pipeInput = initialInput | |
for parent, componentName in components: | |
pipeOutput = object() | |
stub = self.fakeComponent(pipeInput, pipeOutput) | |
self.patch(parent, componentName, stub) | |
pipeInput = pipeOutput | |
result = func(initialInput) | |
#noinspection PyUnboundLocalVariable | |
self.assertIdentical(pipeOutput, result) | |
def test_createPowerCardIsComposition(self): | |
parser = ParserDoodle() | |
# this format is the easiest to pass to the patcher, but if you don't | |
# like the textual references to attributes because it makes IDEA's | |
# job harder, we could use object references and some more | |
# introspection. | |
components = [(parser, fn) for fn in [ | |
'toPowerInfo', | |
'getOnlineInfoForPower', | |
'cleanTheResponse', | |
'createViewModel' | |
]] | |
self.assertIsComposite(parser.createPowerCard, components) | |
def test_createPowerCardIsImplementedLikeThis(self): | |
# This is what my tests of sequence operations often end up feeling | |
# like. | |
parser = ParserDoodle() | |
expected = """\ | |
def createPowerCard(self, powerElement): | |
localInfo = self.toPowerInfo(powerElement) | |
powerDetails = self.getOnlineInfoForPower(localInfo) | |
powerInfo = self.cleanTheResponse(powerDetails) | |
viewModel = self.createViewModel(powerInfo) | |
return viewModel | |
""" | |
self.assertEqual(expected, getsource(parser.createPowerCard)) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment