Monday, September 27, 2010

Dependency injection aids copy and paste coding

In the presence of good documentation or sample code, I love to copy and paste directly out of the documentation or even unit tests, straight into my code.

For example, I was wondering how to add an instance variable to a class in Pharo Smalltalk. Well, I just search my code base for occurrences of addInstanceVariable, and I find this test:

testAddInstanceVariable
| refactoring |
refactoring := AddInstanceVariableRefactoring
variable: 'asdf'
class: RBTransformationRuleTest.
self executeRefactoring: refactoring.
self assert: ((refactoring model classNamed:
#RBTransformationRuleTest)
directlyDefinesInstanceVariable: 'asdf')


Well, that's great, the first few lines are what I need. Some more browsing shows that line 6 is deeply irrelevant for me: the test uses a highly artificial way of executing the test, different from the canonical one.

Is any of that surprising? Not really. There's some papers establishing that this is how a lot of people work: forking work off sample code, but only if it's complex enough to match the use case (cite?).

I think it has an interesting implication for writing unit tests: They should be as close as possible to the intended end user usage. In the example above, my hunch is that the unit test wasn't written in the way that the end user would use the library, because the author feared side effects.

I think here we see one of the great strengths of dependency injection: by moving the part of the unit test that avoids side effects to another level of abstraction, the unit test itself can look exactly as if it had side effects, and thus can serve better as a basis for new work.

No comments:

Post a Comment

Note: Only a member of this blog may post a comment.