The Class Class


Let's tackle the likely concern that a class with the word "Test" in its name is not a junit.framework.TestCase subclass. A test for this case would need to specify a class that the SuiteBuilder can attempt to gather and then reject. You might consider using an existing class that you have already coded for the student information system, such as TestUtil.

However, you do not want to depend on the existence or stability of existing classes. Someone making a valid change to TestUtil, or deleting it, would unwittingly break SuiteBuilderTest tests. You instead will create dummy test classes expressly for the use of SuiteBuilderTest. Start by creating the class NotATestClass in the new package sis.testing.testclasses.

 package sis.testing.testclasses; public class NotATestClass {} 

NotATestClass does not extend junit.framework.TestCase, so it should not be recognized as a test class. Add an assertion to your test method.

 public void testGatherTestClassNames() {    SuiteBuilder builder = new SuiteBuilder();    List<String> classes = builder.gatherTestClassNames();    assertTrue(classes.contains("testing.SuiteBuilderTest"));    assertFalse(classes.contains("testing.testclasses.NotATestClass")); } 

The relevant code in SuiteBuilder:[6]

[6] Note use of the variable name klass to represent a Class object. You can't use class, since Java reserves it for defining classes only. Some developers use the single character c (not recommended), others clazz.

 public List<String> gatherTestClassNames() {    TestCollector collector = new ClassPathTestCollector() {       public boolean isTestClass(String classFileName) {          if (!super.isTestClass(classFileName))             return false;          String className = classNameFromFile(classFileName);   // 1          Class klass = createClass(className);                  // 2          return TestCase.class.isAssignableFrom(klass);         // 3       }    };    return Collections.list(collector.collectTests()); } private Class createClass(String name) {    try {       return Class.forName(name);    }    catch (ClassNotFoundException e) {       return null;    } } 

The additional constraint implemented in SuiteBuilder is that a class filename must represent a compilation unit that extends from TestCase. There are three steps involved. The following descriptions correspond to the commented lines of code in gatherTestClassNames.

1.

Translate the directory-based filename into a class name, for example from "testing/testclasses/NotATestClass" to "testing.testclasses.NotATestClass." The ClassPathTestCollector method classNameFromFile accomplishes this task.

2.

Create a Class object from the class name. In createClass, the static method call of forName, defined on Class, does this. The forName method throws a ClassNotFoundException if the String object you pass to it does not represent a class that can be loaded by Java. For now, you can return null from createClass if this occurs, but you will need to write a test to cover this possibility.

3.

Determine whether the class is a subclass of TestCase. To do so, you will use a method on the class java.lang.Class, which provides metadata about a class definition. The Class method isAssignableFrom takes as a parameter a Class object and returns TRue if it is possible to assign an instance of the parameter (klass, in the above code) to a reference of the receiving class type (junit.framework.TestCase).

Take a brief look at the Java API documentation for java.lang.Class. It contains methods such as getMethods, getConstructors, and getFields that you can use to derive most of the information you need about a compiled Java class.



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