Testing the Application


The student user interface represents an actual application that someone might want to execute and interact with. You will need to provide a main method so that they can start the application. Currently, in order to execute the application, you would need to construct a student UI with System.in and System.out appropriately wrapped, then call the run method.

You can simplify the main method by encapsulating this work in the Student-UI class itself. This may or may not be an appropriate tacticif you only have one user interface class, it's fine. But if you have a dozen related UI classes, each controlling a portion of the user interface, you'd be better off constructing the console wrappers in a single class.

For this example, let's make the main method as simple as possible. You can do this by redirecting console input and output using the System methods setIn and setOut instead of wrapping the input and output streams in buffered streams. You must wrap the ByteArrayOutputStream in a PrintStream in order to call setOut.

 public void testCreateStudent() throws IOException {    StringBuffer expectedOutput = new StringBuffer();    StringBuffer input = new StringBuffer();    setup(expectedOutput, input);    byte[] buffer = input.toString().getBytes();    InputStream inputStream = new ByteArrayInputStream(buffer);    OutputStream outputStream = new ByteArrayOutputStream();    InputStream consoleIn = System.in;    PrintStream consoleOut = System.out;    System.setIn(inputStream);    System.setOut(new PrintStream(outputStream));    try {       StudentUI ui = new StudentUI();       ui.run();       assertEquals(          expectedOutput.toString(),          outputStream.toString());       assertStudents(ui.getAddedStudents());    }    finally {       System.setIn(consoleIn);       System.setOut(consoleOut);    } } 

You want to make sure you reset System.in and System.out by using a try-finally statement.

The new constructor for StudentUI must use an InputStreamReader to wrap stdin in a BufferedReader and an OutputStreamWriter to wrap stdout in a BufferedWriter.

 public StudentUI() {    this.reader =       new BufferedReader(new InputStreamReader(System.in));    this.writer =       new BufferedWriter(new OutputStreamWriter(System.out)); } 

After demonstrating that the test passes, you can now write a main method that kicks off the application.

 public static final void main(String[] args) throws IOException {    new StudentUI().run(); } 

There are two trains of thought on this. First, it is possible to write a test against the main method, since you can call it like any other method (but you must supply an array of String objects that represent command-line arguments):

 StudentUI.main(new String[] {}); 

The other testing philosophy is that the main method is virtually unbreakable. It is one line of code. You will certainly run the application from the command line at least once to ensure it works. As long as the main method does not change, it can't break, in which case you do not necessarily need a test against the main method.

The choice is yours as to whether to test main or not. Regardless, you should strive to minimize the main method to a single line. Refactor code from the main method into either static or instance-side methods. Create utility classes to help you manage command-line arguments. Test the code you move out of main.

I hope you've noticed that testing this simple console-based user interface required a good amount of code. Were you to write more of the console application, the work would simplify as you built utility methods and classes to help both testing and production coding.



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