Encodera

Thanks for reading!

Donate to the site — we work hard for you.

Contents

The first test

A test is an ordinary method in an ordinary class, marked with the @Test annotation. JUnit finds such methods, creates an object of the class and calls them one by one. Inside the method you call your code and compare the result with what you expect. If the values differ, the assertion throws an error and the test is marked as failed.

The test class

Create src/test/java/com/example/shop/PriceCalculatorTest.java — in your IDE, use "New → Java Class" in the src/test/java folder, or IntelliJ IDEA's "Create Test" action on PriceCalculator:

// src/test/java/com/example/shop/PriceCalculatorTest.java
package com.example.shop;
 
import org.junit.jupiter.api.Test;
 
import java.math.BigDecimal;
 
import static org.junit.jupiter.api.Assertions.assertEquals;
 
class PriceCalculatorTest {
 
    @Test
    void totalMultipliesPriceByQuantity() {
        PriceCalculator calculator = new PriceCalculator();
 
        BigDecimal total = calculator.total(new BigDecimal("12.00"), 3);
 
        assertEquals(new BigDecimal("36.00"), total);
    }
}

The test checks that 3 items at $12.00 cost $36.00. Run it with mvn test:

[INFO] Running com.example.shop.PriceCalculatorTest
[INFO] Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.073 s -- in com.example.shop.PriceCalculatorTest
[INFO] BUILD SUCCESS

How it is built

PartMeaning
class PriceCalculatorTestThe name is the class under test plus Test — this is how Surefire finds test classes
@TestMarks the method as a test
void, no parametersA test returns nothing
assertEquals(expected, actual)The expected value comes first, the actual one second
import staticLets you write assertEquals without Assertions. in front

Neither the class nor the method has to be public: package access is enough.

Arrange, act, assert

The empty lines in the test are not random. A good test has three parts:

  1. Arrange — prepare the objects and data: the calculator.
  2. Act — call the method under test once: total().
  3. Assert — check the result: assertEquals.

This pattern makes any test easy to read: what is given, what is done, what is expected.

A second test

Each case is a separate method. Add the discount check to the same class:

// src/test/java/com/example/shop/PriceCalculatorTest.java
@Test
void discountReducesAmount() {
    PriceCalculator calculator = new PriceCalculator();
 
    BigDecimal result = calculator.applyDiscount(new BigDecimal("50.00"), 10);
 
    assertEquals(new BigDecimal("45.00"), result);
}

Now mvn test prints Tests run: 2. The method name describes the expected behavior: when a test fails, its name alone tells you what is broken.

Common mistake

JUnit does not run a test method that is private or returns a value. The project compiles, and the tests are silently missing from the results. JUnit 6 at least warns about it:

WARNING: TestEngine with ID 'junit-jupiter' encountered 2 non-critical issues during test discovery:
 
(1) [WARNING] @Test method 'private void com.example.shop.PrivateTest.totalMultipliesPriceByQuantity()' must not be private. It will not be executed.
(2) [WARNING] @Test method 'int com.example.shop.PrivateTest.returnsValue()' must not return a value. It will not be executed.
...
[INFO] Tests run: 0, Failures: 0, Errors: 0, Skipped: 0

A test method is always void and never private.

Thanks for reading!

Donate to the site — we work hard for you.