An Intertech Course
Junit Best Practices
Course Name
Copyright © Intertech, Inc. • www.Intertech.com • 800-866-9884 Slide 2
Best Practice – What to unit test
• Unit test one object at a time
• Integration tests examine how objects interact with each other
Course Name
Copyright © Intertech, Inc. • www.Intertech.com • 800-866-9884 Slide 3
Best Practice – test method names
• Name test methods so that they are easily identifiable.
• Best practice – call them textX where X is domain method tested.
• Make them as descriptive (therefore long) as necessary
• Older versions of JUnit (JUnit 3 and earlier) required this naming convention.
Course Name
Copyright © Intertech, Inc. • www.Intertech.com • 800-866-9884 Slide 4
Test method pattern
• Test methods follow typical pattern:
• 1 - Set up the test by placing the environment in a known state (create objects,
• acquire resources). The pretest state is referred to as the test fixture.
• 2 - Invoke the method under test.
• 3 - Confirm the result, usually by calling one or more assert methods.
Course Name
Copyright © Intertech, Inc. • www.Intertech.com • 800-866-9884 Slide 5
Best Practice – explain failure
• Use the message parameter (first parameter) with assert methods to provide a meaningful description if the assert fails.
Course Name
Copyright © Intertech, Inc. • www.Intertech.com • 800-866-9884 Slide 6
Best Practice – one test = one test method
• Don’t cram several tests into one method.
• Test methods must be clear and focused.
• Always use assert calls in test methods.
• Exception is when an exception is thrown.
Course Name
Copyright © Intertech, Inc. • www.Intertech.com • 800-866-9884 Slide 7
Best Practice – test anything that could fail
• If a method changes parameters or fields (state) in any way, it needs a test.
• If it can’t break on its own, it is too simple to break.
• How about getters/setters?
• Probably not if the IDE provided them.
• Its really a team decision.
Course Name
Copyright © Intertech, Inc. • www.Intertech.com • 800-866-9884 Slide 8
Best Practice – let tests improve code
• A test case is a user of your code.
• Test cases often show the need for easier-to-use code.
• Lead to refactoring.
• Practice of test-driven development (TDD) relies on this principle.
• As tests are written first, you develop classes from the point of view of a user.
Course Name
Copyright © Intertech, Inc. • www.Intertech.com • 800-866-9884 Slide 9
Testing for exceptions
• Diagnostic tests monitor the application’s health – testing the main or happy path.
• Testing exception handling is just as important.
• Use @Test(expected= )
@Test(expected=RuntimeException.class) public void testGetHandlerNotDefined()
{
SampleRequest request = new SampleRequest("testNotDefined");
//The following line is supposed to throw a RuntimeException
controller.getHandler(request);
}
Course Name
Copyright © Intertech, Inc. • www.Intertech.com • 800-866-9884 Slide 10
Best Practice – make exception tests easy to read
• Name exception test methods to denote exception condition being tested.
• Place comments on the line of code that produces the expected exception.
• Identify exception paths by looking for branches.
• May find that too many branches make testing “painful.”
• This may indicate poor design.
• Requires some refactoring – splitting a larger method into several smaller methods.
• Again – test code is a user – the first user – of your code.
• Hard to write test cases means hard to use code.
Course Name
Copyright © Intertech, Inc. • www.Intertech.com • 800-866-9884 Slide 11
Timeouts
• How do you test how scalable code might be?
• Use @Test(timeout=) to test against a time barrier (in milliseconds)
@Test(timeout=130)
public void testProcessMultipleRequestsTimeout()
{
Request request;
Response response = new SampleResponse();
RequestHandler handler = new SampleHandler();
for(int i=0; i< 99999; i++)
{
request = new SampleRequest(String.valueOf(i));
controller.addHandler(request, handler);
response = controller.processRequest();
assertNotNull(response);
assertNotSame(ErrorResponse.class, response.getClass());
}
}
Course Name
Copyright © Intertech, Inc. • www.Intertech.com • 800-866-9884 Slide 12
Ignoring a test
• @Ignore on a test method causes the runner to skip the test.
• Not available in JUnit3.
• Best practice (box on the page) is to always specify a reason for skipping a test.
Course Name
Copyright © Intertech, Inc. • www.Intertech.com • 800-866-9884 Slide 13
Hamcrest Matchers
• Asserts may get to be too long/hard to read.
• Hamcrest library provides a set of matching rules that can be used in asserts.
• Example – anyOf versus use of many ||
• Hamcrest library is available at http://code.google.com/p/hamcrest
• Some good/simple examples can also be found here:
• http://edgibbs.com/junit-4-with-hamcrest/
Course Name
Copyright © Intertech, Inc. • www.Intertech.com • 800-866-9884 Slide 14
Project Organization
• Put tests in the same package, different source folders (directories).
• Allows test classes to unit test protected methods.
• Avoids clutter of too many classes (domain + test) in one folder
• Allows test code to be easily removed for production JAR.
• Also a best practice.
• Testing private methods…
• Testing private methods indicates those methods should be moved into another class to promote reusability.
• You can use reflection to subvert the access control mechanism.
• See http://junit.sourceforge.net/doc/faq/faq.htm#tests_9