Skip to main content

Notice: this Wiki will be going read only early in 2024 and edits will no longer be possible. Please see: https://gitlab.eclipse.org/eclipsefdn/helpdesk/-/wikis/Wiki-shutdown-plan for the plan.

Jump to: navigation, search

Better Exception Testing in ICE with J-Unit

Better JUNIT Testing

In many developing software applications (including ICE), unit testing has become a vital role in developing reliable, safer, and more robust products. JUNIT is one of the tools that can be used to run unit and integration tests for Java-based applications in test-driven development. Below is an example of utilizing better methods for developing unit tests for handling Exceptions on tested objects with the testing tool.


Here is a sample exception try/catch statement within a JUnit test:

//A class that tests the operation
//StringToIntegerUtility.customStrToInt(String number)
@Test
public void checkStringToInteger() {
 
    //Local declaration
 
    int number;
    String number = "Not a number";
    boolean expectedFail = false;
 
    //Setup class
    StringToIntegerUtility utility = new StringToIntegerUtility();
 
    //Call operation with try/catch statement
    try {
        number = utility.customStrToInt(number);
    } catch (NumberFormatException e) {
        //We expect this to happen
        expectedFail = true;
    }
 
    //Test is valid if it failed
    assertTrue(expectedFail);
 
}


When the utility operation is called, there has to be a try/catch statement. Try/catch statements can clutter code and confuse some forms of unit testing. What can be done is to separate these specific exception unit tests into their own methods and have JUNIT check the exceptions. Below is a better way to handle the exceptions in a JUNIT test.

//A class that tests the operation
//StringToIntegerUtility.customStrToInt(String number)
@Test(expected=java.lang.NumberFormatException.class)
public void checkStringToInteger() throws NumberFormatException {
    //Local declaration
    int number;
    String number = "Not a number";
 
    //Setup class
    StringToIntegerUtility utility = new StringToIntegerUtility();
 
    //Call operation, and this operation should
    //throw an exception.
    number = utility.customStrToInt(number);
 
}


This method cuts down on some of the more excessive try/catch statements in unit testing. It also helps to modularize the codebase in unit testing by separating out the exception cases from other tests. The expected statement catches the exception when it is thrown. Nevertheless, there are some limitations to this method. For example, when the exception is thrown, the testing ends in that method. Thus, if one were to need to write more expansive tests that utilize many exceptions, there would need to be an individual method for each exception. Secondly, this can pose a problem for identifying messages in exceptions for generic Exception handling or classes with multiple types of references. The second issue can be resolved by using the thrown.expect(class) and thrown.expectMessage(String) from the JUnit API. These types of calls are declared within the method and not annotated.


Locations of Exceptions

There are many areas in ICE where native and customized exceptions are thrown and caught within the applications. Many of them are required by overloaded applications, while others are created to catch specific errors in ICE. Below is a list of the operations that throw and/or catch exceptions within ICE's general architecture. It will also mention if the error prints out a stack trace or not. If it does, it will mention whether or not the operation is handled within the method. Note that just printing a stack trace does not constitute an operation as "being handled". Returning false on a boolean method for a failed initialization of another method because of a try/catch statement is an example of "handling" an issue.


This is a table for exceptions caught within each method.

ICEClient
Class Method Exception Prints a stack trace? Handles error?
EclipseFormWidget display() PartInitException Yes No
EclipseTestEditor display() PartInitException Yes No
ICEFormEditor addPages() PartInitException Yes No
ICEMatrixComponentSectionPart modify() NumberFormatException No No
ICEGeometryPage createFormContent() PartInitException Yes No
GeometryApplication commit() ClassCastException No No
RealSpinner validateText() NumberFormatException No Yes
ShapeMaterial applyShape() NumberFormatException No No
Itemprocessor run() InterruptedException Yes No


ICECore
Class Method Exception Prints a stack trace? Handles error?
BasicAuthSecuredContext failedAuthorization() IOException Yes No
BasicAuthSecuredContext getResource() MalformedURLException No Yes
BasicAuthSecuredContext handleSecurity() LoginException Yes Yes
ICECore start() ServletException, NamespaceException, IOException All yes All no
ICECore setLocation() CoreException Yes Yes
ICECore loadDefaultAreaItems() IOException, CoreException All yes Yes, No
SimpleLogin login() IOException, UnsupportedLoginException All yes All yes


ICEDataStructures
Class Method Exception Prints a stack trace? Handles error?
DataComponent, Entry, Form, MasterDetailsComponent loadFromXML() NullPointerException, JAXBException, IOException All yes All yes
MasterDetailsPair, MatrixComponent, TableComponent loadFromXML() NullPointerException, JAXBException, IOException All yes All yes
ComplexShape, GeometryComponent, PrimitiveShape loadFromXML() NullPointerException, JAXBException, IOException All yes All yes
Transformation, ICEObject, ICEResource loadFromXML() NullPointerException, JAXBException, IOException All yes All yes
Entry setValue() NumberFormatException No Yes
AbstractShape getProperty() IndexOutOfBoundsException No Yes
ICEObject persistToXML() NullPointerException, JAXBException, IOException Yes No
ICEResource setContents() NullPointerException No Yes


ICEItem
Class Method Exception Prints a stack trace? Handles error?
Item process() CoreException Yes No
Item loadFromXML() IOException, JAXBException, IOException Yes Yes
Item persistToDatabase() Exception Yes Yes
Item deleteFromDatabase() Exception Yes Yes
Item updateToDatabase() Exception Yes Yes
Item loadFromDatabase() Exception Yes Yes
JobLaunchAction createSession() JschException Yes No
JobLaunchAction BufferedWriter() IOException Yes No
JobLaunchAction isLocalHost() UknownHostException Yes No
JobLaunchAction launchLocally() IOException Yes Yes
JobLaunchAction launchRemotely() InterruptedException, JschException, FileNotFoundException, SftpException All yes All no
TaggedOutputWriterAction execute() IOException Yes Yes
JobLauncher createOutputFiles() CoreException, IOException All yes All no
JobLauncher setupForm() CoreException Yes No
JobLauncher loadFromXML() IOException, JAXBException, NullPointerException Yes Yes
MultiLauncher run() InterruptedException Yes No
JobProfile process() CoreException Yes No


This is a table for a list of exceptions thrown within each method of each class. Usually when an exception is thrown, an issue is handled in a higher level operation/method. Therefore "handles error" does not apply here.


ICEClient
Class Method Exception Prints a stack trace?
EntryComposite EntryComposite() RuntimeException No
ICEDataComponentSectionPart ICEDataComponentSectionPart() RuntimeException No
ICEFormEditor Init() RuntimeException No
ICEMatrixComponentSectionPart ICEMatrixComponentSectionPart() RuntimeException No
ICESectionPage ICESectionPage() RuntimeException No
ICETableComponentSectionPart ICETableComponentSectionPart() RuntimeException No
ShapeTransient read() IOException No
ShapeTransient write() IOException No
Tube read() IOException No
Tube write() IOException No


ICECore
Class Method Exception Prints a stack trace?
BasicAuthSecuredContext handleSecurity() IOException No
BasicAuthSecuredContext login() IOException, UnsupportedCallbackException, LoginException No
SimpleLogin abort() LoginException No
SimpleLogin commit() LoginException No
SimpleLogin login() LoginException No
ICECoreIApplication start() Exception No


ICEDataStructures
Class Method Exception Prints a stack trace?
Form addComponent() RuntimeException No
PainfullySimpleEntry loadFromPSFBlock() IOException No
PainfullySimpleForm loadComponents() IOException No
PainfullySimpleForm loadEntries() IOException No
ICEJAXBManipulator read() JAXBException, IOException No
ICEJAXBManipulator write() JAXBException, IOException No
ICEResource ICEResource() IOException No
ICEResource setContents() IOException, NullPointerException No


ICEItem
Class Method Exception Prints a stack trace?
Item Item() RuntimeException No
Item loadFromPSF() IOException No
SerializedItemBuilder SerilaizedItemBuilder() IOException No

References

http://weblogs.java.net/blog/johnsmart/archive/2009/09/27/testing-exceptions-junit-47

http://kentbeck.github.com/junit/javadoc/4.10/org/junit/rules/ExpectedException.html

Back to the top