Using JUnit Code


Fortunately, JUnit supplies a mechanism that will help you gather the test classes on the classpath. How would you know that? First, you might have run JUnit and observed that it has the capability to gather a list of all test classes. Following up on that, you could have perused the source distributed with JUnit and seen that it has a class named junit.runner.ClassPathTestCollector.

You will create a class named SuiteBuilder to gather all test classes. A simple first test for SuiteBuilder would ensure that SuiteBuilderTest itself was returned in the list of test classes found on the classpath.

 package sis.testing; import junit.framework.*; import java.util.*; public class SuiteBuilderTest extends TestCase {    public void testGatherTestClassNames() {       SuiteBuilder builder = new SuiteBuilder();       List<String> classes = builder.gatherTestClassNames();       assertTrue(classes.contains("testing.SuiteBuilderTest"));    } } 

The interesting part of the test is that it binds the list to the String typenot the Class type. When you look at the source for ClassPathTestCollector, you will note that it returns an Enumeration of Strings, each representing the class name. We'll go along with that for now and see if it causes any problems later.

 package sis.testing; import java.util.*; import junit.runner.*; import junit.framework.*; public class SuiteBuilder {    public List<String> gatherTestClassNames() {       TestCollector collector = new ClassPathTestCollector() {          public boolean isTestClass(String classFileName) {             return super.isTestClass(classFileName);          }       };       return Collections.list(collector.collectTests());    } } 

The ClassPathTestCollector is declared as abstract, so you must extend it in order to instantiate it. Interestingly, there are no abstract methods contained within, meaning you are not required to override any of ClassPathTestCollector's methods. You will want to override the method isTestClass:

 protected boolean isTestClass(String classFileName) {    return       classFileName.endsWith(".class") &&       classFileName.indexOf('$') < 0 &&       classFileName.indexOf("Test") > 0; } 

The query method isTestClass concerns itself only with the class filenames, not with the structure of the classes themselves. The conditional states that if a filename ends in a .class extension, does not contain a $ (i.e., it does not represent a nested class), and contains the text "Test," then it is a test class.

You might recognize that this definition could cause problems: What if a file with a .class extension is not a valid class file? What if the class name contains the text "Test" but is not a test class? The last condition is highly likely. Your own code for the student information system contains the class util.TestUtil, which is not a TestCase subclass.

You're not going to worry about these problems (yet) since your test doesn't (yet) concern itself with any of these cases. For now, your implementation code in getTestClassNames overrides isTestClass and simply calls the superclass method to use its existing behavior. This is unnecessary, but it acts as a placeholder and reminder when you are ready to take care of the other concerns.

The last line of gatherTestClassNames sends the message collectTests to the ClassPathTestCollector. Somewhere along the way, collectTests indirectly calls isTestClass. The return type of collectTests is java.util.Enumeration. You can use the java.util.Collections utility method list to transform the Enumeration into an ArrayList. You will get an unchecked warning, since ClassPathTestCollector uses raw collectionscollections not bound to a specific type.



Agile Java. Crafting Code with Test-Driven Development
Agile Javaв„ў: Crafting Code with Test-Driven Development
ISBN: 0131482394
EAN: 2147483647
Year: 2003
Pages: 391
Authors: Jeff Langr

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net