August 20, 2018
Hot Topics:

Working With Design Patterns: Factory Method

  • August 28, 2008
  • By Jeff Langr
  • Send Email »
  • More Articles »

Inheritance hierarchies containing an abstract base class present a small challenge for unit testing: How do common superclass methods get tested? Because you can't instantiate an abstract class, should you create an extension of it solely for purposes of testing? Or, do you re-test each of the public inherited methods for each subclass? Maybe it's sufficient simply to exercise the set of subclasses.

I can rule out the last choice: Public behavior needs to be explicitly tested, so it is not sufficient to test only against the subclass public methods. The first option, creating a test-only subclass of the target (the class being tested), is theoretically not a bad idea. It demonstrates that the public behavior works with stubbed implementations for abstract methods. In practice, though, it's probably best if the common public behavior works in conjunction with every derived class. No question then remains as to whether the public behavior works in context with the concrete class code.

That leaves you with the second choice—re-test each public method in each subclass. The downside is that this could generate a lot of redundant test code. Consider listing 1, which shows the test for a FloatColumn class. FloatColumn is an abstraction of an SQL column used for an object-to-relational mapping tool. Each such SQL column class requires a name upon construction, and must return that name when asked (via a getName method call). The common code in FloatColumn and other types like StringColumn and DateColumn can obviously be pushed into a base class, perhaps AbstractColumn. Listing 2 shows the relevant portions of both FloatColumn and AbstractColumn.

Listing 1: FloatColumnTest.

package persistence.types;

import static org.junit.Assert.*;
import org.junit.*;

public class FloatColumnTest {
   protected Column column;
   static final String NAME = "name";

   public void setUp() {
      column = new FloatColumn("name");

   public void create() {
      assertEquals("name", column.getName());

   public void isEqualToColumnWithSameName() {

   public void isUnequalToColumnWithDifferentName() {
      assertFalse(column.equals(createColumn(NAME + "x")));

   public void isUnequalToNull() {

   public void isUnequalToObjectOfDifferentType() {

   public void isUnequalToObjectOfSubtype() {
      Column subInstance = new FloatColumn(NAME) {

   public void hashIsEqualForEqualObjects() {

   private Column createColumn(String name) {
      return new FloatColumn(name);

   // ... other specific FloatColumn tests ...

Listing 2: The Column class implementations.

// AbstractColumn.java
package persistence.types;

abstract public class AbstractColumn implements Column {
   private String name;

   public AbstractColumn(String name) {
      this.name = name;

   public String getName() {
      return name;

   public boolean equals(Object object) {
      if (this == object) return true;
      if (object == null || !(object instanceof Column) ||
         object.getClass() != this.getClass())
         return false;
      Column that = (Column)object;
      return this.getName().equals(that.getName());

   public int hashCode() {
      return getName().hashCode();
   // ...

// FloatColumn.java
package persistence.types;

public class FloatColumn extends AbstractColumn {
   public FloatColumn(String name) {
   // ...

Page 1 of 3

Comment and Contribute


(Maximum characters: 1200). You have characters left.



Enterprise Development Update

Don't miss an article. Subscribe to our newsletter below.

By submitting your information, you agree that developer.com may send you developer offers via email, phone and text message, as well as email offers about other products and services that developer believes may be of interest to you. developer will process your information in accordance with the Quinstreet Privacy Policy.


Thanks for your registration, follow us on our social networks to keep up-to-date