Refactoring test units after an extract method

Steve Howell showell30 at yahoo.com
Tue Jun 5 09:28:59 EDT 2007


--- Virgil Dupras <hardcoded.software at gmail.com>
wrote:

> How to you handle the tests? Copy over the tests you
> had for foo() and
> apply them to bar()? I don't like copy and pasting
> code. Move the B
> related tests to baz()'s tests? Then your tests
> wouldn't fail if you
> stopped calling baz() in foo() and bar().
> 

I recently had an example where class A used class B,
which used class C, which used class D, which used OS
service E, etc.  I had mock versions of B, C, D, and
E.  The overall design of the module was kind of like
a network stack, where each module theoretically only
depended on the services of the module beneath it in
the stack.  

So many of the tests for A used a real B, but a mock
C.

Many of the tests for B used a real C, but a mock D.

Many of the tests for C used a real D, but a mock E.

But I also wanted to test that my abstractions weren't
leaky, e.g. that there weren't some implementation
details of C or lower that broke A.  So certain loops
in my test for A would also plug in a real C.

Finally, some of the test for A would also use a mock
B.

I was able to mostly avoid copy-and-pasting of tests
by taking advantage of Python's dynamic nature. 
Although this is oversimplifying things a bit, you can
do things like this:

for b_is_mocked, c_is_mocked, d_is_mocked in [
     (True, True, True),
     (True, True, False),
     (False, False, False), # etc.
     ]
     # do setup
     test1()
     test2()
     test3()
     test4()







       
____________________________________________________________________________________
Sick sense of humor? Visit Yahoo! TV's 
Comedy with an Edge to see what's on, when. 
http://tv.yahoo.com/collections/222



More information about the Python-list mailing list