如何使用Mockito测试指定的if条件判断语句?
Let's break down how to test this conditional logging behavior. We need to cover two key scenarios: when the response status is >= 400 (SC_BAD_REQUEST) and when it's not. Here's a step-by-step solution using Mockito and JUnit 5.
First, Context: The Class Under Test
Let's assume your code lives in a class like this (adjust the class name as needed):
import javax.servlet.http.HttpServletResponse; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import javax.ws.rs.core.Response; public class TraceService { private static final Logger LOGGER = LoggerFactory.getLogger(TraceService.class); public void handleTraceEnregistrement(Response reponse) { if (reponse.getStatus() >= HttpServletResponse.SC_BAD_REQUEST) { LOGGER.error("Erreur lors de l'enregistrement de la trace technique - {}", reponse.getStatusInfo().getReasonPhrase()); } } }
Scenario 1: Test When Status >= 400 (Logs Error)
We need to mock the Response object to return a 400+ status, then verify the logger's error method is called with the correct message. Since LOGGER is a static field, we'll use Mockito's mockStatic to mock the LoggerFactory.
import org.junit.jupiter.api.Test; import org.mockito.MockedStatic; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import javax.ws.rs.core.Response; import static javax.servlet.http.HttpServletResponse.SC_BAD_REQUEST; import static org.mockito.Mockito.*; class TraceServiceTest { private final TraceService traceService = new TraceService(); @Test void handleTraceEnregistrement_StatusBadRequestOrHigher_LogsError() { // Arrange Response mockResponse = mock(Response.class); // Use real Response.Status enum for cleaner setup (no need to mock StatusInfo) when(mockResponse.getStatus()).thenReturn(SC_BAD_REQUEST); when(mockResponse.getStatusInfo()).thenReturn(Response.Status.BAD_REQUEST); // Mock the static logger factory to return our mock logger try (MockedStatic<LoggerFactory> mockedLoggerFactory = mockStatic(LoggerFactory.class)) { Logger mockLogger = mock(Logger.class); mockedLoggerFactory.when(() -> LoggerFactory.getLogger(TraceService.class)).thenReturn(mockLogger); // Act traceService.handleTraceEnregistrement(mockResponse); // Assert: Verify the error log was called with the exact message verify(mockLogger).error("Erreur lors de l'enregistrement de la trace technique - {}", "Bad Request"); } } }
Scenario 2: Test When Status < 400 (No Error Log)
Here, we'll set the response status to 200 (OK) and verify the logger's error method is never called.
@Test void handleTraceEnregistrement_StatusOk_DoesNotLogError() { // Arrange Response mockResponse = mock(Response.class); when(mockResponse.getStatus()).thenReturn(200); // SC_OK try (MockedStatic<LoggerFactory> mockedLoggerFactory = mockStatic(LoggerFactory.class)) { Logger mockLogger = mock(Logger.class); mockedLoggerFactory.when(() -> LoggerFactory.getLogger(TraceService.class)).thenReturn(mockLogger); // Act traceService.handleTraceEnregistrement(mockResponse); // Assert: Ensure error log was not triggered verify(mockLogger, never()).error(anyString(), any()); } }
Alternative: If Logger Is Injectable (Better Practice)
If you can refactor your class to use constructor injection for the logger (instead of static), the test becomes simpler (no need for mockStatic):
Refactored Class
import javax.servlet.http.HttpServletResponse; import org.slf4j.Logger; import javax.ws.rs.core.Response; public class TraceService { private final Logger LOGGER; public TraceService(Logger logger) { this.LOGGER = logger; } public void handleTraceEnregistrement(Response reponse) { if (reponse.getStatus() >= HttpServletResponse.SC_BAD_REQUEST) { LOGGER.error("Erreur lors de l'enregistrement de la trace technique - {}", reponse.getStatusInfo().getReasonPhrase()); } } }
Simplified Test
import org.junit.jupiter.api.Test; import org.slf4j.Logger; import javax.ws.rs.core.Response; import static javax.servlet.http.HttpServletResponse.SC_BAD_REQUEST; import static javax.servlet.http.HttpServletResponse.SC_OK; import static org.mockito.Mockito.*; class TraceServiceTest { private final Logger mockLogger = mock(Logger.class); private final TraceService traceService = new TraceService(mockLogger); @Test void handleTraceEnregistrement_StatusBadRequestOrHigher_LogsError() { Response mockResponse = mock(Response.class); when(mockResponse.getStatus()).thenReturn(SC_BAD_REQUEST); when(mockResponse.getStatusInfo()).thenReturn(Response.Status.BAD_REQUEST); traceService.handleTraceEnregistrement(mockResponse); verify(mockLogger).error("Erreur lors de l'enregistrement de la trace technique - {}", "Bad Request"); } @Test void handleTraceEnregistrement_StatusOk_DoesNotLogError() { Response mockResponse = mock(Response.class); when(mockResponse.getStatus()).thenReturn(SC_OK); traceService.handleTraceEnregistrement(mockResponse); verify(mockLogger, never()).error(anyString(), any()); } }
Key Notes
- Dependencies: Ensure you have Mockito Core and Mockito Inline (for static mocking) in your build. For Maven, add:
<dependency> <groupId>org.mockito</groupId> <artifactId>mockito-core</artifactId> <version>5.6.0</version> <scope>test</scope> </dependency> <dependency> <groupId>org.mockito</groupId> <artifactId>mockito-inline</artifactId> <version>5.6.0</version> <scope>test</scope> </dependency> - Real Enum Usage: Using
Response.Status.BAD_REQUESTinstead of mockingStatusInfoensures you're testing against real API behavior, which is more reliable. - Verification: Use
verify(..., never())to confirm the logger isn't called when it shouldn't be—this is just as important as verifying it is called when it should.
内容的提问来源于stack exchange,提问作者Alirin

