Junior
What is a mock in testing?
sobes.tech AI
Answer from AI
Mock — is a stub object that fully imitates the behavior of a real dependent component or service in a testing environment. It allows controlling the return values of dependency methods and checking how the tested code interacts with them.
Main differences from other test stubs (Stubs, Fakes):
- Stub: Provides predefined responses to method calls but does not verify interaction.
- Fake: Has a working but simplified implementation of a dependent component.
- Mock: Mimics behavior, provides predefined responses, and most importantly, allows verifying how the tested code interacted with this object (e.g., which methods were called, how many times, with what arguments).
Purposes:
- Isolating the tested code from external dependencies (databases, external services, file systems, etc.).
- Accelerating test execution.
- Testing boundary cases and error handling, which are difficult to reproduce with real dependencies.
- Verifying expected interactions between objects.
Example of usage with Mockito:
// Interface to be mocked
public interface UserService {
User findUserById(long userId);
}
// Class that uses UserService and will be tested
public class UserController {
private final UserService userService;
public UserController(UserService userService) {
this.userService = userService;
}
public String getUserName(long userId) {
User user = userService.findUserById(userId);
if (user != null) {
return user.getName();
}
return "User not found";
}
}
// Test class using mocks
import org.junit.jupiter.api.Test;
import static org.mockito.Mockito.*;
import static org.junit.jupiter.api.Assertions.*;
public class UserControllerTest {
@Test
void getUserName_UserFound() {
// Create a mock of UserService
UserService mockUserService = mock(UserService.class);
// Define mock behavior: when findUserById(1) is called, return a User
User mockUser = new User(1, "John Doe");
when(mockUserService.findUserById(1)).thenReturn(mockUser);
// Create the object under test, passing the mock
UserController userController = new UserController(mockUserService);
// Call the method under test
String userName = userController.getUserName(1);
// Assert the result
assertEquals("John Doe", userName);
// Verify that findUserById was called once with argument 1
verify(mockUserService, times(1)).findUserById(1);
}
@Test
void getUserName_UserNotFound() {
UserService mockUserService = mock(UserService.class);
// Define mock behavior: when findUserById(any long), return null
when(mockUserService.findUserById(anyLong())).thenReturn(null);
UserController userController = new UserController(mockUserService);
String userName = userController.getUserName(2);
assertEquals("User not found", userName);
// Verify that findUserById was called once
verify(mockUserService, times(1)).findUserById(anyLong());
}
// Helper class for the example
static class User {
private final long id;
private final String name;
public User(long id, String name) {
this.id = id;
this.name = name;
}
public long getId() { return id; }
public String getName() { return name; }
}
}