Test layer
- Java course
- Advanced
- Lesson 76/82
- 6 min
Write tests with JUnit and Mockito.
LedgerService and its test
In this lesson you will write a LedgerService class and its unit test. The service is a thin layer that adds records and counts them.
class LedgerService {
ArrayList<Transaction> ledger = new ArrayList<>();
void add(Transaction t) { ledger.add(t); }
int getCount() { return ledger.size(); }
}The test class LedgerServiceTest adds one record and verifies getCount() with assertEquals(1, ...). This adds a reliable test layer to the app.
Verifying with assertEquals
assertEquals(expected, actual) compares the expected and actual values. If they are equal the test passes; otherwise it throws and fails. This is the basic verification tool for unit tests.
@Test
void testGetCount() {
LedgerService s = new LedgerService();
s.add(new Transaction("market", 120));
assertEquals(1, s.getCount());
}Here, after adding one record, getCount() should return 1. The first argument is expected, the second is actual. Keeping tests in a separate class (not in main) keeps production code clean.
Practice Write LedgerServiceTest
Define a LedgerServiceTest class. Write a @Test method testGetCount that adds one record and calls assertEquals(1, s.getCount()). In Main, create a LedgerService, add two records and print service.getCount() with System.out.println.
Starter code
import java.util.ArrayList;
import java.util.concurrent.*;
class Transaction {
String category;
int amount;
Transaction(String category, int amount) {
this.category = category;
this.amount = amount;
}
}
class LedgerService {
ArrayList<Transaction> ledger = new ArrayList<>();
void add(Transaction t) { ledger.add(t); }
int getCount() { return ledger.size(); }
}
public class Main {
public static void main(String[] args) throws Exception {
LedgerService service = new LedgerService();
service.add(new Transaction("market", 120));
service.add(new Transaction("fuel", 80));
// Call the test class and print the getCount result
}
}Sample solution
import java.util.ArrayList;
import java.util.concurrent.*;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.*;
class Transaction {
String category;
int amount;
Transaction(String category, int amount) {
this.category = category;
this.amount = amount;
}
}
class LedgerService {
ArrayList<Transaction> ledger = new ArrayList<>();
void add(Transaction t) { ledger.add(t); }
int getCount() { return ledger.size(); }
}
class LedgerServiceTest {
@Test
void testGetCount() {
LedgerService s = new LedgerService();
s.add(new Transaction("market", 120));
assertEquals(1, s.getCount());
}
}
public class Main {
public static void main(String[] args) throws Exception {
LedgerService service = new LedgerService();
service.add(new Transaction("market", 120));
service.add(new Transaction("fuel", 80));
System.out.println(service.getCount());
}
}Expected output
2
Questions and answers
Review the lesson questions together with their answers. To test yourself, solve the lesson interactively.
1 Complete the @Test annotation
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.*;
class LedgerServiceTest {
____
void testGetCount() {
LedgerService s = new LedgerService();
s.add(new Transaction("market", 120));
assertEquals(1, s.getCount());
}
}
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.*;
class LedgerServiceTest {
@Test
void testGetCount() {
LedgerService s = new LedgerService();
s.add(new Transaction("market", 120));
assertEquals(1, s.getCount());
}
}
Explanation: A method marked with @Test runs as a test.
2 When does assertEquals(1, s.getCount()) fail?
- When @Test is missing
- When the class compiles
- When there is no main
- When getCount() does not return 1 Correct answer
Explanation: If getCount() returns something other than 1, the assertion fails.
3 Match the test concepts
| Term | Meaning |
|---|---|
LedgerService |
Adds and counts |
LedgerServiceTest |
Test class |
@Test |
Test method marker |
assertEquals |
Value verification |