SpringBoot(JUnit4+Mockito)下Mock Retrofit编写单元测试求助
JUnit4 + Mockito Unit Tests for Retrofit Gmail Token Extraction
Great question! Let's break down how to write unit tests for your extractGmail method using JUnit4 and Mockito. The goal is to isolate your method's logic by mocking all external dependencies (Retrofit components and the Google API interface), so we don't make real calls to Google's servers during testing.
Complete Test Class
Assuming your extractGmail method lives in a service class like TokenValidationService (replace this with your actual class name), here's the full test code:
import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.InjectMocks; import org.mockito.Mock; import org.mockito.junit.MockitoJUnitRunner; import retrofit2.Call; import retrofit2.Response; import static org.junit.Assert.assertEquals; import static org.mockito.Mockito.*; @RunWith(MockitoJUnitRunner.class) public class TokenValidationServiceTest { // Mock the Retrofit API interface to avoid real API calls @Mock private GoogleTokenValidatorAPI googleTokenValidatorAPI; // Inject mocked dependencies into the service under test @InjectMocks private TokenValidationService tokenValidationService; // Replace with your actual service class @Test public void extractGmail_ValidToken_ReturnsEmail() throws IOException { // 1. Setup test data String validToken = "valid-google-token-123"; String expectedEmail = "john.doe@nineleaps.com"; GmailDTO mockGmailResponse = new GmailDTO(); mockGmailResponse.setEmail(expectedEmail); mockGmailResponse.setHd("nineleaps.com"); // 2. Mock Retrofit's Call and Response objects Call<GmailDTO> mockCall = mock(Call.class); Response<GmailDTO> successfulResponse = Response.success(mockGmailResponse); // 3. Define mock behavior when(googleTokenValidatorAPI.authenticateUsingGmail(validToken)).thenReturn(mockCall); when(mockCall.execute()).thenReturn(successfulResponse); // 4. Run the method under test String actualEmail = tokenValidationService.extractGmail(validToken); // 5. Verify results and interactions assertEquals(expectedEmail, actualEmail); verify(googleTokenValidatorAPI, times(1)).authenticateUsingGmail(validToken); verify(mockCall, times(1)).execute(); } @Test(expected = Unauthorized.class) public void extractGmail_UnsuccessfulApiResponse_ThrowsUnauthorized() throws IOException { // 1. Setup test data String invalidToken = "invalid-google-token-456"; // 2. Mock an unsuccessful API response (e.g., 401 Unauthorized) Call<GmailDTO> mockCall = mock(Call.class); Response<GmailDTO> errorResponse = Response.error(401, null); // 3. Define mock behavior when(googleTokenValidatorAPI.authenticateUsingGmail(invalidToken)).thenReturn(mockCall); when(mockCall.execute()).thenReturn(errorResponse); // 4. Execute method (should throw exception) tokenValidationService.extractGmail(invalidToken); } @Test(expected = Unauthorized.class) public void extractGmail_WrongDomain_ThrowsUnauthorized() throws IOException { // 1. Setup test data String validTokenWrongDomain = "valid-token-wrong-domain-789"; GmailDTO mockGmailResponse = new GmailDTO(); mockGmailResponse.setEmail("jane.doe@otherdomain.com"); mockGmailResponse.setHd("otherdomain.com"); // 2. Mock successful response with wrong domain Call<GmailDTO> mockCall = mock(Call.class); Response<GmailDTO> successfulResponse = Response.success(mockGmailResponse); // 3. Define mock behavior when(googleTokenValidatorAPI.authenticateUsingGmail(validTokenWrongDomain)).thenReturn(mockCall); when(mockCall.execute()).thenReturn(successfulResponse); // 4. Execute method (should throw exception) tokenValidationService.extractGmail(validTokenWrongDomain); } @Test(expected = Unauthorized.class) public void extractGmail_NullResponseBody_ThrowsUnauthorized() throws IOException { // 1. Setup test data String tokenWithNullBody = "token-with-null-body-000"; // 2. Mock successful response with null body (edge case) Call<GmailDTO> mockCall = mock(Call.class); Response<GmailDTO> nullBodyResponse = Response.success(null); // 3. Define mock behavior when(googleTokenValidatorAPI.authenticateUsingGmail(tokenWithNullBody)).thenReturn(mockCall); when(mockCall.execute()).thenReturn(nullBodyResponse); // 4. Execute method (should throw exception) tokenValidationService.extractGmail(tokenWithNullBody); } }
Key Concepts Explained
- @RunWith(MockitoJUnitRunner.class): Enables Mockito's annotation support for JUnit4, handling mock initialization automatically.
- @Mock: Creates fake instances of
GoogleTokenValidatorAPI,Call, andResponseso we don't rely on real Retrofit or Google API functionality. - @InjectMocks: Automatically injects the mocked
GoogleTokenValidatorAPIinto your service class, eliminating the need for manual dependency setup. - Test Scenarios:
- Valid Token: Tests the happy path where the API response is successful and the domain matches, returning the user's email.
- Unsuccessful Response: Tests when the API returns an error (like 401), triggering the
Unauthorizedexception. - Wrong Domain: Tests when the response is valid but the
hd(hosted domain) doesn't match "nineleaps.com". - Null Response Body: Covers an edge case where the API returns a successful status but no body, preventing a
NullPointerExceptionin your method.
Additional Tips
- If
Unauthorizedis a runtime exception (not declared inextractGmail'sthrowsclause), the@Test(expected = Unauthorized.class)annotation will still work correctly. - If your service uses constructor injection instead of field injection, Mockito will still handle
@InjectMocksas long as the constructor parameters match the mocked fields.
内容的提问来源于stack exchange,提问作者Bhavesh jain
相关产品推荐
相关产品推荐

