Wednesday, 11 June 2025

Mockito in JUnit with relational database (Or) NoSQL

Mockito in JUnit

 Mockito is a popular Java framework used in JUnit testing to create mock objects. These mock objects simulate real dependencies, making unit testing faster, isolated, and more reliable.

Why Use Mockito?

  • Isolate dependencies: Avoid calling actual services, databases, or APIs.
  • Improve test performance: No need to connect to external systems.
  • Control method behavior: Define return values for methods.
  • Verify interactions: Ensure methods are called with expected parameters.

Basic Mockito Annotations

1️⃣ @Mock → Creates a mock object.

@Mock
private DepartmentService departmentService;

2️⃣ @InjectMocks → Injects mock objects into the class being tested.

@InjectMocks private DepartmentController departmentController;

3️⃣ @BeforeEach → Initializes mocks before each test.

@BeforeEach void setUp() { MockitoAnnotations.openMocks(this); }

Example: Unit Test for DepartmentController

@ExtendWith(MockitoExtension.class) // JUnit 5 (JUnit Jupiter) public class DepartmentControllerTest { @Mock private DepartmentService departmentService; @InjectMocks private DepartmentController departmentController; private Department department; @BeforeEach void setUp() { MockitoAnnotations.openMocks(this); department = Department.builder() .departmentId(1L) .departmentName("IT") .departmentAddress("New York") .departmentCode("IT-001") .build(); } @Test void testSaveDepartment() { when(departmentService.saveDepartment(any(Department.class))).thenReturn(department); Department savedDepartment = departmentController.saveDepartment(department); assertNotNull(savedDepartment); assertEquals("IT", savedDepartment.getDepartmentName()); } @Test void testFetchDepartmentById() throws DepartmentNotFoundException { when(departmentService.fetchDepartmentById(1L)).thenReturn(department); Department foundDepartment = departmentController.fetchDepartmentById(1L); assertNotNull(foundDepartment); assertEquals(1L, foundDepartment.getDepartmentId()); } @Test void testDeleteDepartmentById() { String response = departmentController.deleteDepartmentById(1L); assertEquals("Department deleted Successfully!!", response); verify(departmentService, times(1)).deleteDepartmentById(1L); } }

Key Mockito Methods

  1. when(...).thenReturn(...) → Mock method behavior.
    when(departmentService.fetchDepartmentById(1L)).thenReturn(department);
  2. any(Class.class) → Match any argument of that class.
    when(departmentService.saveDepartment(any(Department.class))).thenReturn(department);
  3. verify(..., times(n)) → Ensure a method was called n times.
    verify(departmentService, times(1)).deleteDepartmentById(1L);
  4. doThrow(...).when(...).method() → Simulate exceptions.
    doThrow(new DepartmentNotFoundException("Not Found")).when(departmentService).fetchDepartmentById(2L);

Mockito vs. Real Objects

FeatureReal ObjectMockito Mock
Calls real methods?✅ Yes❌ No
Affects real data?✅ Yes❌ No
Faster execution?❌ No✅ Yes
Dependency isolation?❌ No✅ Yes


1) We can write JUnit tests for a Spring Boot Controller layer using @WebMvcTest with Mockito, while the backend uses MS SQL Server(relational database).

✅ Scenario Overview for relational databases

  • Database: MS SQL Server (via Spring Data JPA)

  • Test: Controller using @WebMvcTest

  • Mocking: UserService

  • HTTP testing: MockMvc

๐Ÿ“ฆ 1. User.java (Entity)
@Entity
@Table(name = "users")
public class User {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    private String name;
    private String email;
    // Constructors, Getters, Setters
}

๐Ÿ“ฆ 2. UserRepository.java

public interface UserRepository extends JpaRepository<User, Long> { }

๐Ÿ“ฆ 3. UserService.java

@Service
public class UserService { @Autowired private UserRepository userRepository; public User saveUser(User user) { return userRepository.save(user); } public List<User> getAllUsers() { return userRepository.findAll(); } public Optional<User> getUserById(Long id) { return userRepository.findById(id); } public void deleteUser(Long id) { userRepository.deleteById(id); } }

๐Ÿ“ฆ 4. UserController.java

@RestController @RequestMapping("/api/users") public class UserController { @Autowired private UserService userService; @PostMapping public ResponseEntity<User> createUser(@RequestBody User user) { return new ResponseEntity<>(userService.saveUser(user), HttpStatus.CREATED); } @GetMapping public ResponseEntity<List<User>> getAllUsers() { return ResponseEntity.ok(userService.getAllUsers()); } @GetMapping("/{id}") public ResponseEntity<User> getUserById(@PathVariable Long id) { return userService.getUserById(id) .map(ResponseEntity::ok) .orElse(ResponseEntity.notFound().build()); } @DeleteMapping("/{id}") public ResponseEntity<Void> deleteUser(@PathVariable Long id) { userService.deleteUser(id); return ResponseEntity.noContent().build(); } }

๐Ÿ‘‰ Key Point:
in @WebMvcTest tests, the actual database (MSSQL Or MongoDB) is not involved — we mock the service layer, so it doesn't matter which database is used.

✅ 5. UserControllerTest.java@WebMvcTest + Mockito

@WebMvcTest(UserController.class) class UserControllerTest { @Autowired private MockMvc mockMvc; @MockBean private UserService userService; private User user; @BeforeEach void setUp() { user = new User(); user.setId(1L); user.setName("John"); user.setEmail("john@example.com"); } @Test void testCreateUser() throws Exception { when(userService.saveUser(any(User.class))).thenReturn(user); mockMvc.perform(post("/api/users") .contentType(MediaType.APPLICATION_JSON) .content("{\"name\":\"John\", \"email\":\"john@example.com\"}")) .andExpect(status().isCreated()) .andExpect(jsonPath("$.name").value("John")) .andExpect(jsonPath("$.email").value("john@example.com")); } @Test void testGetAllUsers() throws Exception { when(userService.getAllUsers()).thenReturn(List.of(user)); mockMvc.perform(get("/api/users")) .andExpect(status().isOk()) .andExpect(jsonPath("$.length()").value(1)) .andExpect(jsonPath("$[0].name").value("John")); } @Test void testGetUserById() throws Exception { when(userService.getUserById(1L)).thenReturn(Optional.of(user)); mockMvc.perform(get("/api/users/1")) .andExpect(status().isOk()) .andExpect(jsonPath("$.name").value("John")); } @Test void testDeleteUser() throws Exception { doNothing().when(userService).deleteUser(1L); mockMvc.perform(delete("/api/users/1")) .andExpect(status().isNoContent()); } }

๐Ÿงช Dependencies Required in pom.xml

Make sure your pom.xml includes:

<!-- Spring Boot Starter Test --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <!-- For JSONPath in tests --> <dependency> <groupId>com.jayway.jsonpath</groupId> <artifactId>json-path</artifactId> <scope>test</scope> </dependency>

✅ Summary

LayerTool UsedNotes
Controller@WebMvcTestTests only controller, not service/repo
Service@MockBeanService is mocked to isolate controller
DBMS SQLNot used in controller test

------------------------------------------------------------
2)We can write a JUnit + Mockito + @WebMvcTest test class for a Spring Boot Controller that uses MongoDB.
✅ Scenario Setup: MongoDB-based User CRUD

๐Ÿ“ฆ User.java

@Document(collection = "users") public class User { @Id private String id; private String name; private String email; // Getters and Setters }

๐Ÿ“ฆ UserRepository.java

public interface UserRepository extends MongoRepository<User, String> { }

๐Ÿ“ฆ UserService.java same as above

๐Ÿ“ฆ UserController.java same as above

UserControllerTest.java – JUnit + Mockito + @WebMvcTest same as above

๐Ÿ“ฆ Maven Dependencies (If not already present)

Make sure your test scope dependencies include:

<!-- Spring Boot Starter Test --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <!-- Mockito Core --> <dependency> <groupId>org.mockito</groupId> <artifactId>mockito-core</artifactId> <scope>test</scope> </dependency>

✅ Summary

  • @WebMvcTest isolates only the controller.

  • @MockBean is used to inject a mocked UserService—the database (MongoDB) isn’t touched.

  • Use MockMvc to simulate HTTP requests.

  • Since MongoDB is abstracted behind the service, you don't need to mock the repository for controller tests.


No comments:

Post a Comment