In this tutorial, we will learn how to perform Micronaut Unit testing for Controllers and Services. We will build a simple Student Management example using com.kscodes.micronaut package structure, and then create tests using JUnit 5 and Mockito.

As you have gone through Creating REST Endpoints with @Controller and @Get/@Post, lets see how Micronaut Unit testing for this is done.
Project Setup
We will create a simple Student Management system where we can:
- Add a new student
- Retrieve student details
Dependencies
In your pom.xml, make sure you have these dependencies:
io.micronaut
micronaut-inject
io.micronaut
micronaut-http-client
org.junit.jupiter
junit-jupiter-engine
test
org.mockito
mockito-core
test
io.micronaut.test
micronaut-test-junit5
test
Create the Application Code
Student Model
package com.kscodes.micronaut.model;
public class Student {
private String id;
private String name;
public Student(String id, String name) {
this.id = id;
this.name = name;
}
public String getId() {
return id;
}
public String getName() {
return name;
}
}
StudentService
package com.kscodes.micronaut.service;
import com.kscodes.micronaut.model.Student;
import jakarta.inject.Singleton;
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;
@Singleton
public class StudentService {
private final Map students = new HashMap<>();
public void addStudent(Student student) {
students.put(student.getId(), student);
}
public Optional getStudent(String id) {
return Optional.ofNullable(students.get(id));
}
}
StudentController
package com.kscodes.micronaut.controller;
import com.kscodes.micronaut.model.Student;
import com.kscodes.micronaut.service.StudentService;
import io.micronaut.http.HttpResponse;
import io.micronaut.http.annotation.*;
import jakarta.inject.Inject;
import java.util.Optional;
@Controller("/students")
public class StudentController {
@Inject
private StudentService studentService;
@Post
public HttpResponse addStudent(@Body Student student) {
studentService.addStudent(student);
return HttpResponse.ok("Student added successfully");
}
@Get("/{id}")
public HttpResponse getStudent(@PathVariable String id) {
Optional student = studentService.getStudent(id);
return student.map(HttpResponse::ok)
.orElseGet(() -> HttpResponse.notFound());
}
}
Unit Testing the Service
Since StudentService is simple and has no external dependencies, we can write pure unit tests.
package com.kscodes.micronaut.service;
import com.kscodes.micronaut.model.Student;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
public class StudentServiceTest {
@Test
public void testAddAndGetStudent() {
StudentService service = new StudentService();
Student student = new Student("1", "John Doe");
service.addStudent(student);
Assertions.assertTrue(service.getStudent("1").isPresent());
Assertions.assertEquals("John Doe", service.getStudent("1").get().getName());
}
@Test
public void testGetStudentNotFound() {
StudentService service = new StudentService();
Assertions.assertFalse(service.getStudent("unknown").isPresent());
}
}
Unit Testing the Controller
For the controller, we mock the StudentService dependency.
package com.kscodes.micronaut.controller;
import com.kscodes.micronaut.model.Student;
import com.kscodes.micronaut.service.StudentService;
import io.micronaut.test.extensions.junit5.annotation.MicronautTest;
import jakarta.inject.Inject;
import org.junit.jupiter.api.Test;
import org.mockito.Mockito;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.junit.jupiter.MockitoExtension;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import io.micronaut.http.HttpResponse;
import java.util.Optional;
import static org.junit.jupiter.api.Assertions.*;
import static org.mockito.Mockito.*;
@ExtendWith(MockitoExtension.class)
public class StudentControllerTest {
@Mock
StudentService studentService;
@InjectMocks
StudentController studentController;
@Test
public void testAddStudent() {
Student student = new Student("1", "John Doe");
HttpResponse response = studentController.addStudent(student);
verify(studentService, times(1)).addStudent(student);
assertEquals(200, response.getStatus().getCode());
assertEquals("Student added successfully", response.body());
}
@Test
public void testGetStudentFound() {
Student student = new Student("1", "John Doe");
when(studentService.getStudent("1")).thenReturn(Optional.of(student));
HttpResponse response = studentController.getStudent("1");
assertEquals(200, response.getStatus().getCode());
assertEquals("John Doe", response.body().getName());
}
@Test
public void testGetStudentNotFound() {
when(studentService.getStudent("2")).thenReturn(Optional.empty());
HttpResponse response = studentController.getStudent("2");
assertEquals(404, response.getStatus().getCode());
}
}
Summary
- Use pure unit tests for services with no dependencies.
- Use mocks (e.g. Mockito) to isolate controller tests from the service layer.
- Micronaut makes testing simple with its dependency injection and fast startup time.