Today's submitter gave us their name as simply ImminentBurnout. IB works at a company that uses Python and has strong opinions about unit testing. They don't have much understanding to go with those opinions, but they definitely have opinions.
One opinion is that every object- every object must have a stub version to facilitate unit testing. Now, if you're familiar with Python, you know the MagicMock
library is built-in in Python 3 and is available as a dependency in 2.7, so problem solved. A MagicMock
can act as a stub for every class or method. Plus, it has patching operators to dynamically swap out implementations.
And if IB's workplace used MagicMock
, we wouldn't have much to say.
Instead, they had an in-house generic module which would generate the boilerplate for you. IB doesn't tell us much about how this module is actually used- how you mark a class to have a mock generated.
But IB did share with us the implementation of the mock. Python's a flexible language, and there are a million ways you could accomplish this (even though MagicMock
or a related library is probably the "right" answer).
One thing that's important to note is that, in Python, you can include arbitrary code in the class body. So something like this is perfectly valid:
>>> x = 5
>>> class Foo:
... if x:
... def bar(self):
... return x
... else:
... def bar(self):
... return 2
...
>>> f = Foo()
In this example, the definition of bar
will change depending on the value of the variable x
. This is generally not a good thing to do, but it's important to note that you can add loops, declare variables, and call functions from inside of the class body.
So, inside the body of the mock-generating class, how exactly did they leverage this feature of the language?
impl_def1 = ' retval = self.extend_f( "%s" %s %s )\n' \
' try:\n' \
' if retval == None:\n' \
' retval = %s\n' \
' except:\n' \
' pass\n' \
' return retval' \
% ( method_name, comma, ', '.join( input_defs ), ', '.join( output_defs ) )
impl_def2 = ' _ = self.extend_f( "%s" )\n' \
' return' % ( method_name )
impl_def = impl_def1 if len( output_defs ) else impl_def2
stub_def = 'def method( %s ):\n%s' % ( ', '.join( input_defs ), impl_def )
exec(stub_def)
They do a pile of string-mungning then invoke exec
, which as you might guess, executes a string as if it were Python code. That's the WTF, but they somehow managed to make string-munging more awkward and uglier than it needed to be.
There are a few things we can see in this code. First, the heavy use of the %
operator implies that it started life in an older version of Python, where string formatting worked more like: "This %s is %s" % ("code", "bad")
. So that could excuse not using MagicMock
, perhaps, but there are still far better ways to do this. The bonus of using the older-style string formatting is that it helps make it basically impossible to parse out what's actually getting injected in each block- which values exactly end up in the line retval = %s\n
?
You'll also note that they used the most awkward possible option for doing multiline strings, as Python supports (and has nearly always supported) using """
as the boundary for multiline strings.
IB has this to add:
It's so bad that it cured my impostor syndrome. I may not be the best, but at least I don't write this kind of crap.
And that, by the way, is the cure for imposter syndrome: realize that the world is full of successful morons, so no matter how much of a moron you think you are, you're entitled to whatever success you have.