4. Unit Tests
At the end of the objects review topic the implementation was played with
This allowed testing the basic functionality
However, the testing was far from through or systematic
4.1. Unit Testing
Ideally, when testing code, each unit or component should be tested
Unit Testing
Ideally with good coverage
When doing so, individual test methods are written to test the units/components
These tests can also be run automatically
By writing tests like this, it adds intentionality to the code and tests
Take the time to think of the cases needing testing
It can also help keep the units/components isolated
It also obviously helps with testing and debugging
It there are ever breaking changes to the unit/component being tested, the automated testing should find it
Writing tests can be a bit of an art, so it’s best to get a lot of practice
4.2. JUnit
JUnit is a very popular unit testing framework for Java
It’s simple to use and automates testing
Within IntelliJ, there is a simple way to setup JUnit
Make a new folder/directory called
test
in the project next tosrc
Right click the
test
folder and select Mark Directory as -> Test Sources RootCreate a new class for testing named such that it is the class name followed by “Test”
For example,
FriendTest
Add JUnit to the class path
A simple way to do it is to write
@Test
in the new class and press Alt + Enter
Select Add ‘JUnit5…
Do not select Junit 4… as that will cause issues with the tests
4.3. Testing the Friend Class
Checkout the
FriendTest.java
for testing theFriend
classFor now, the new ideas introduced here are
@Test
annotation — marking a method as a testAssertions — a mechanism for checking something
Below are excerpts from the
FriendTest
class
10 @Test
11 void getFirstName_generalCase_returnsFirstName() {
12 Friend friend = new Friend("qwerty", "asdfgh", "zxcvbn");
13 assertEquals("qwerty", friend.getFirstName());
14 }
Consider the first test within the test class as shown above
The method is marked with
@Test
to mark the method as a test method for JunitIt has a descriptive name of the form
unitUnderTest_case_expectedResult
getFirstName_generalCase_returnsFirstName
getFirstName
is the method being testedSince there is no real special condition or case for this test, it has
generalCase
in its namereturnsFirstName
is the expected result of calling the method
It uses
assertEquals
to check that the expected string"qwerty"
is what is returned bygetFirstName()
30 @Test
31 void equals_equalFriendObjects_areEqual() {
32 Friend aFriend = new Friend("qwerty", "asdfgh", "zxcvbn");
33 Friend bFriend = new Friend("qwerty", "asdfgh", "zxcvbn");
34 assertEquals(aFriend, bFriend);
35 }
Consider the above two tests
equals_equalFriendObjects_areEqual
equals_unequalFriendObjects_areNotEqual
These tests are named such that the cases (equal/unequal
Friend
objects) is clearThese tests also make use of different asserts
assertEquals
assertNotEquals
Warning
The above tests for equality are sufficient for the purposes of this course, but they could be improved. Within the
provided FriendTest
class is a test method that makes use of EqualsVerifier
, which helps with testing
equality on objects. Although this improved equality test is provided, the simpler equality tests are fine here. Do
note that EqualsVerifier
is an external dependency that is not included with Java or IntelliJ.
52 @Test 53 void equals_verify_contract() { 54 EqualsVerifier.forClass(Friend.class) 55 .withNonnullFields("firstName") 56 .withNonnullFields("lastName") 57 .withNonnullFields("email") 58 .verify(); 59 }
4.4. For Next Time
Read Chapter 1 of the text
15 pages
4.4.1. Playing Code
Download and play with