As part of his talk on integration tests J.B. Rainsberger talked about how contract tests can be used to test the interaction between classes when using a mockist approach to developer testing. He wondered aloud if it would be possible to write these kinds of tests using abstract classes and JUnit 4. The answer is yes, with some caveats, as I demonstrate in the screencast below. Enjoy!
EDIT: If the embedded screencast below doesn't work for you, try this link.
Do you prefer this inheritance based scheme to jUnit Theories?
Posted by: Chris Vest | December 29, 2009 at 08:04 AM
Great example, thank you.
One off topic question - what plug-in do you use to run tests? I like the way its UI is minimized at the bottom of workspace. Also it looks like it's able to run only changed tests, right?
Posted by: Oleg | December 29, 2009 at 08:25 AM
Oleg,
The plug-in used to run the tests in this screencast is called Infinitest.
http://improvingworks.com/products/infinitest/
It not only runs changed tests, but selects an optimized subset of tests to run based on what you've changed (a feature not particularly apparent in a simple example like this). It's available with both a free and commercial license.
Posted by: Ben Rady | December 29, 2009 at 09:07 AM
Using JUnit theories for something like this seems to me like it would violate the Open-Closed Principle, because in order to test a new type of list, youd have to go into the test and change it to include the new type.
Is there a way to use theories for this that doesnt suffer from that problem?
Posted by: Ben Rady | December 29, 2009 at 09:18 AM
Interesting. I had a related problem where I had to write abstract contract tests but the classes to be tested only become known at runtime (through dependency injection). I ended up writing my own test runner that works with test classes that have a constructor with one parameter, like MyTest(List). I.e., the actual object to be tested is passed to the test case when it is instantiated. If you are interested, the project is treaty: http://code.google.com/p/treaty/, the respective code can be seen here:
http://code.google.com/p/treaty/source/browse/tags/release2.1.1/treaty-eclipse-voc-junit/src/net/java/treaty/eclipse/vocabulary/junit/TestRunner.java
Posted by: Jens Dietrich | March 03, 2010 at 01:55 AM
(I haven't watched Rainsberger's presentation yet, so maybe this question is addressed in there. Apologies if it is.)
The problem with making test classes inherit from one another is that you're limited by single inheritance. Say you've got a FileRepository class and a ReadableRepository interface, and you've written test classes for both. A ReadableFileRepository extends FileRepository and implements ReadableRepository. Is there a simple way to write a test class containing ReadableFileRepository specific tests, which also runs the test cases for FileRepository and ReadableRepository?
Thanks,
Emerson
Posted by: Emerson Farrugia | September 23, 2010 at 12:28 PM