Transcript NameList

Unit Testing
Part 2: Drivers and Stubs
CSIS 3701: Advanced Object Oriented Programming
Testing Support Classes
• Support class not executable program
• Need another executable program to run tests
– Construct support objects
– Call methods
– Display/check object state for correctness
• Key: other “tester” program must be simple
– Any errors must be in support class, not tester!
NameList Example
Main.java
NameList.java
• Stores names
• Returns current names
names
• Validates list not full,
name not already in list
Are errors here?
Or are they in the testing tool itself?
Current
application
may not use
all methods
in class
Drivers
• Simple program to test other code
• Example: function driver for C++ sqrt function
int main() {
double test;
while(1) {
cout << “Enter test case: “;
cin >> test;
cout << sqrt(test) << ‘\n’;
}
}
Class Drivers in Java
• Must be in a main method
– Separate testing class
– As main in support class itself
NameList.java
• Idea:
keep testing tools as part of class
Constructors
and methods
main method
to test these
– Do not delete when finished testing
• Will need again if class modified in future
Class Drivers in Java
• Example:
Simple driver for add method in NameList
public static void main(String[] args) {
NameList n = new NameList(3);
while(true) {
String name =
JOptionPane.showInputDialog(null, "Enter name");
n.add(name);
JOptionPane.showMessageDialog(null, n.toString());
}
}
Class Drivers in Java
• May need additional code for exceptions
public static void main(String[] args) {
NameList n = new NameList(3);
while(true) {
String name = JOptionPane.showInputDialog(null, “Name:");
try {n.add(name);}
catch (FullListException ex) {
JOptionPane.showMessageDialog(null, "List full!");
}
catch (InListException ex) {
JOptionPane.showMessageDialog(null, “In list!");
}
JOptionPane.showMessageDialog(null, n.toString());
}
Class Dependency
• What if your class depends on other classes?
– May not be available immediately if being developed
by others
– Still need to compile and test your code
• Cannot afford to wait around for others!
• Example: Developing main visual application without
working NameList class
Class Dependency
Main.java
NameList.java
NameList constructor
void add(String)
int getSize()
String getNameByIndex(int)
boolean isIn(String)
boolean isFull()
NameList names
This class does not exist yet
Nor do these constructors or
methods
NameList Example
• None of the following code will work!
public void actionPerformed(ActionEvent e) {
String name = nameField.getText();
if (names.isIn(name))
JOptionPane.showMessageDialog(this, name + " already in list");
else {
names.add(name);
for (int i = 0; i < names.getSize(); i++)
namesArea.append(names.getNameByIndex(i) + "\n");
if (names.isFull()) addButton.setEnabled(false);
}
Stubs
• Stub: temporary code to take place of code still
in development
– Replaced with actual code when available
– Must allow thorough testing of your code
• All methods, branches, etc.
– Must be simple
• Easy to create
• Unlikely to contain own bugs
Stub Function Example
• Simple C++ example:
Your code:
…
function();
…
Function written
by other
developer and
not currently
available
stub code:
void function() {}
Simplest possible stub –
will allow your code to
compile and run
Stub Function Example
• Can include diagnostic messages to help test
– Is external function called at correct time?
– Is it called with correct parameters?
Your code:
…
function(a);
…
stub code:
void function(int x) {
cout << “function called with “
<< x << “ as parameter\n”;
}
Diagnostic message displayed
Stub Function Example
• May need to return value to help test your code
– Can be simple “hard wired” value
– Can prompt for return value if needed to test branches
b = function(a);
if (b > 0) {
…
}
else {…}
function must return
values greater than and
less than 0 to test both
branches
int function(int x) {
cout << “function called with “
<< x << “ as parameter\n”;
cout << “What should it return?”;
int y;
cin >> y;
return y;
}
Can perform one test that returns 1 and another
that returns -1
Stub Classes
• Takes place of entire class during testing
– No state variables
– Stubs for constructors/methods called by your code
• Example: NameList stub for testing main:
– Stub NameList constructor  display parameter
– Stub add method  display parameter,
prompt for whether to throw exception
– Stub getSize method  prompt for int to return
– Stub isIn method  prompt to return true or false
– Stub isFull method  prompt to return true or false
– Stub getNameByIndex method  return dummy value
NameList Stub
public class NameListStub {
public NameListStub(int max) {
System.out.println("constructor called with "+max);
}
public String getNameByIndex(int index) {
return "Stub Name";
}
public int getSize() {
String response = JOptionPane.showInputDialog(null,
"What is list size?");
return Integer.parseInt(response);
}
NameList Stub
public boolean isIn(String name) {
String response = JOptionPane.showInputDialog(null,
"Is "+name+" in list?");
return response.equals("true");
}
public boolean isFull() {
String response = JOptionPane.showInputDialog(null,
"Is list full?");
return response.equals("true");
}
NameList Stub
public void add(String name) {
System.out.println("add called with "+name);
String response =
JOptionPane.showInputDialog(null,
“1) No exception\n2 List full\n3) In list");
Prompt for whether to
throw an exception
if (response.equals(“1”)) return;
if (response.equals(“2”))
throw new FullListException();
if (response.equals(“3”))
throw new InListException();
}
Throw appropriate exception type (must
have stubs for these also)!