 JMU - Department of Computer Science
Stubs and Drivers

## 1 Overview

For a variety of different reasons (that we don't have the space to go into here), it is almost always a good idea to develop and test software in "pieces".

At first glance this may seem impossible because it is hard to imagine how you can test one "piece" if the other "pieces" that it uses have not yet been developed (and vice versa). The way around this conundrum is to use stubs and drivers.

Though it is possible to define stubs and drivers at some length, that's not necessary for our purposes here. Instead, we will use the following definitions:

 Stub A piece of code that simulates the activity of missing components. Driver A piece of code that passes test cases to another piece of code.

## 2 An Example

We now consider an example in which we need to develop a "calculator" that converts between different units (e.g., feet to inches).

We start by "stubbing-out" the UnitConverter class. This "stubbed-out" class contains comments that describe the class and all of the methods that we expect it to have (appropriately commented). All of the non-void methods return an appropriate default so that the class can be compiled.

/**
* Converts from one unit to another (e.g., inches to feet)
*
* @author  Prof. David Bernstein, James Madison University
* @version 0.1   (Stub)
*/
public class UnitConverter
{

/**
* Default Constructor
*/
public UnitConverter()
{

}

/**
* Perform a conversion
*
* @param value    The number to convert
* @param from     The units for value (e.g., "inches")
* @param to       The units to convert to (e.g., "feet")
* @return         The converted value
*/
public double convert(double value, String from, String to)
{

return 0.0;
}

/**
* Get the multiplier needed for a conversion
*
* @param from     The units to convert from (e.g., "inches")
* @param to       The units to convert to (e.g., "feet")
* @return         What "from" needs to be multiplied by to get "to"
*/
public double getMultiplier(String from, String to)
{

return 0.0;
}

}


We next write a preliminary driver that can be used to perform preliminary tests of the UnitConverter class. In this version the method calls to the UnitConverter are all "hard-coded".

/**
* A driver for testing the UnitConverter class
*
* @author  Prof. David Bernstein, James Madison University
* @version 1.0
*/
public class Driver
{
/**
* The entry point of the application
*
* @param args   The command-line arguments
*/
public static void main(String[] args)
{
double                converted, original;
String                from, to;
UnitConverter         calculator;

calculator = new UnitConverter();

from      = "inches";
to        = "feet";
original  = 10.0;
converted = calculator.convert(original, from, to);
System.out.println(original+" "+from+" = "+converted+" "+to);

}

}


Note that these two classes can be compiled and executed.

The next version of the UnitConverter contains a complete implementation of the convert method but still contains a stub of the getMultiplier method (which has been changed slightly to make it more useful). This enables us to test the convert method (using the driver) independently from the other methods.

/**
* Converts from one unit to another (e.g., inches to feet)
*
* @author  Prof. David Bernstein, James Madison University
* @version 0.2   (Implemented convert)
*/
public class UnitConverter
{

/**
* Default Constructor
*/
public UnitConverter()
{

}

/**
* Perform a conversion
*
* @param value    The number to convert
* @param from     The units for value (e.g., "inches")
* @param to       The units to convert to (e.g., "feet")
* @return         The converted value
*/
public double convert(double value, String from, String to)
{
double     result;

result = value * getMultiplier(from, to);
return result;
}

/**
* Get the multiplier needed for a conversion
*
* @param from     The units to convert from (e.g., "inches")
* @param to       The units to convert to (e.g., "feet")
* @return         What "from" needs to be multiplied by to get "to"
*/
public double getMultiplier(String from, String to)
{

return 1.0 / 12.0;
}

}


The next version of the UnitConverter contains an implementation (though not a very good one) of the getMultiplier method.

/**
* Converts from one unit to another (e.g., inches to feet)
*
* @author  Prof. David Bernstein, James Madison University
* @version 1.0   (Implemented getMultiplier)
*/
public class UnitConverter
{

/**
* Default Constructor
*/
public UnitConverter()
{
}

/**
* Perform a conversion
*
* @param value    The number to convert
* @param from     The units for value (e.g., "inches")
* @param to       The units to convert to (e.g., "feet")
* @return         The converted value
*/
public double convert(double value, String from, String to)
{
double     result;

result = value * getMultiplier(from, to);
return result;
}

/**
* Get the multiplier needed for a conversion
*
* @param from     The units to convert from (e.g., "inches")
* @param to       The units to convert to (e.g., "feet")
* @return         What "from" needs to be multiplied by to get "to"
*/
public double getMultiplier(String from, String to)
{
double        multiplier;

multiplier = 1.0;
if        (from.equals("inches")) {

if      (to.equals("feet"))   multiplier = 1.0/12.0;
else if (to.equals("yards"))  multiplier = 1.0/12.0/3.0;
else if (to.equals("miles"))  multiplier = 1.0/12.0/3.0/1760.0;

} else if (from.equals("feet")) {

if      (to.equals("inches")) multiplier = 12.0;
else if (to.equals("yards"))  multiplier = 1.0/3.0;
else if (to.equals("miles"))  multiplier = 1.0/3.0/1760.0;

} else if (from.equals("yards")) {

if      (to.equals("inches")) multiplier = 3.0*12.0;
else if (to.equals("feet"))   multiplier = 3.0;
else if (to.equals("miles"))  multiplier = 1.0/1760.0;

} else if (from.equals("miles")) {

if      (to.equals("inches")) multiplier = 12.0*3.0*1760.0;
else if (to.equals("yards"))  multiplier = 1760.0;
else if (to.equals("feet"))   multiplier = 3.0*1760.0;
}

return multiplier;
}

}


To test this version of the UnitConverter we need to modify the driver so that it generates more test cases. In this case we use "white-box (or glass-box) testing" (i.e., we look at the UnitConverter class to identify important test cases) and write a driver that tests all supported inputs.

/**
* A driver for testing the UnitConverter class
*
* @author  Prof. David Bernstein, James Madison University
* @version 2.0
*/
public class Driver
{
/**
* The entry point of the application
*
* @param args   The command-line arguments
*/
public static void main(String[] args)
{
double                converted, original;
int                   i, j;
String                from, to;
String[]              units = {"inches","feet","yards","miles"};
UnitConverter         calculator;

calculator = new UnitConverter();

original  = 10.0;

for (i=0; i < units.length; i++) {
for (j=0; j < units.length; j++) {

from      = units[i]; // This could be outside the inner loop
to        = units[j];
converted = calculator.convert(original, from, to);
System.out.println(original+" "+from+" = "+converted+" "+to);
}
}
}

}


This process continues until a satisfactory version of the UnitConverter is completed.