Test Case
T
/**
* TEST CASE - Example using AssertEquals
* -----------------------------------------------------
* A "test case" verifies one specific expected behavior.
*
* In this example:
* - Behavior: average of squared numbers is computed correctly
*
* We use the AAA pattern (Arrange, Act, Assert) which provides a
* clean and readable structure for writing test cases.
*
* ARRANGE: Set up objects and initial state
* ACT: Execute the method under test
* ASSERT: Verify the result matches the expectation
*/
package com.minte9.junit.test_case;
import org.junit.Test;
import static org.junit.Assert.assertEquals;
import java.util.ArrayList;
import java.util.List;
public class CaseTest {
@Test
public void mytest() { // This method is the TEST CASE
// ARRANGE
Squares squares = new Squares();
squares.add(3); // 9
squares.add(5); // 25
// ACT
int actual = squares.average(); // 9 + 25 = 34/2
int expected = 17;
// ASSERT
assertEquals(actual, expected); // passed
}
}
class Squares {
private final List<Integer> squares = new ArrayList<>();
public void add(int x) {
squares.add(x * x);
}
public int average() {
int total = squares.stream()
.mapToInt(Integer::intValue)
.sum();
return total / squares.size();
}
}
With Generics
T
/**
* TEST CASES WITH GENERICS
* ------------------------
* This example demonstrates how to write JUnit test cases for a
* class that uses Java Generics, specificlly a slit that accepts
* only numeric types (T exntends Number).
*
* WHAT WE ARE TESTING:
* --------------------
* 1. That MyList<Integer> correctly sums integer values.
* 2. That MyList<Double> correctly sums double values (via intValue()).
* 3. That the sum is returned as an int, regardless of numeric type.
* 4. That type safety prvents invalid comaparitions (comparing to a String).
*
* WHY T EXTENDS NUMBER?
* ---------------------
* By restricting the type parameter to subclasses of Number, we gain
* access to Number methods such as intValue(), doubleValue(), etc.
* This makes it possible to process generically-typed numeric values.
*
* JUNIT ASSERTIONS:
* -----------------
* assertEquals(expected, actual)
* assertNotEquals(unexpected, actual)
*/
package com.minte9.junit.test_case;
import org.junit.Test;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotEquals;
import java.util.ArrayList;
import java.util.List;
public class GenericsTest {
@Test
public void integers() {
MyList<Integer> numbers = new MyList<>();
numbers.add(3);
numbers.add(5);
assertEquals(numbers.sum(), 8); // expected, actual
}
@Test
public void doubles() {
MyList<Double> numbers = new MyList<>();
numbers.add(3.0);
numbers.add(5.0);
assertEquals(numbers.sum(), 8); // sum() returns int
assertNotEquals(numbers.sum(), "8.0"); // not equal to string
}
}
class MyList<T extends Number> {
private List<T> items = new ArrayList<>();
public void add(T t) {
items.add(t);
}
public int sum() {
return items.stream()
.mapToInt(Number::intValue)
.sum();
}
}
With Lambdas
T
/**
* TEST CASE - LAMBDAS + FUNCTINAL INTERFACE EXAMPLE
* -------------------------------------------------
* This example shows how JUnit can be used to test code that relies
* on functional interfaces and lambda expressions.
*
* KEY CONCEPTS:
* -------------
* 1) A @FunctionalInterface is an interface with exactly ONE abstract method.
* It is designed to be implemented using a lambda expression.
*
* 2) Lambdas provide behavior as a value:
* () -> 3 * 3
*
* 3) A test case can verify not only data but also behavior supplied via lambdas.
*
* WHAT THIS TEST CHECKS:
* ----------------------
* - Two lambda functions representing "squaring operations" are stored.
* - Each lambda is executed via Square::get.
* - The average of all computed squares is correctly returned.
*/
package com.minte9.junit.test_case;
import org.junit.Test;
import static org.junit.Assert.assertEquals;
import java.util.ArrayList;
import java.util.List;
public class LambdasTest {
@Test
public void mytest() {
// ARRANGE
SQ squares = new SQ();
squares.add(() -> 3 * 3); // lambda for 9
squares.add(() -> 5 * 5); // lambda for 25
// ACT
int actual = squares.average(); // (9 + 25) / 2 = 17
// ASSERT
assertEquals(actual, 17); // passed
}
}
class SQ {
private List<Square> squares = new ArrayList<>();
public void add(Square s) {
squares.add(s);
}
public int average() {
int total = squares.stream()
.mapToInt(Square::get) // execute lambda
.sum();
return total / squares.size();
}
}
// Functional interface: designed for lambdas
@FunctionalInterface
interface Square {
int get();
}
Questions and answers:
Clink on Option to Answer
1. What does a “test case” verify?
- a) A single specific expected behavior
- b) The whole application workflow
2. What is the correct order of the AAA Pattern?
- a) Act → Arrange → Assert
- b) Arrange → Act → Assert
3. In the Squares example, what does the test assert?
- a) That the average of squared numbers is computed correctly
- b) That the list contains only even numbers
4. In MyList
- a) To allow using numeric methods like intValue()
- b) To allow storing strings
5. Why does sum() in MyList return an int for both Integers and Doubles?
- a) Because streams convert values using intValue()
- b) Because doubles cannot be stored in a list
6. What makes Square a functional interface?
- a) It has exactly one abstract method
- b) It has multiple abstract methods
7. What does .mapToInt(Square::get) do in the lambda example?
- a) Executes each lambda and converts the results to ints
- b) Filters only even values
8. Why can lambdas be tested in JUnit?
- a) Because lambdas are stored as behavior and can be invoked like methods
- b) Because lambdas always return the same result