Android中Github搜索响应解析函数的单元测试用例及传参问题
Hey there! Let's tackle your Android unit testing question step by step. First, I'll show you how to craft valid and invalid JSONObject samples to pass into your function, then walk through writing test cases that cover both successful parsing and error scenarios. I'll also cover when and how to mock JSONObject if you need to.
Since you want to test actual parsing logic (not just mocked behavior), using real JSONObject instances is the best approach for valid/invalid scenario testing. Here's how to build them:
1.1 Valid Sample JSON (With "items" Array)
This matches the structure your function expects, with all required fields for each repository:
private JSONObject createValidResponseJson() throws JSONException { JSONObject response = new JSONObject(); JSONArray items = new JSONArray(); // First repository entry JSONObject repo1 = new JSONObject(); repo1.put("name", "android-test-sample"); repo1.put("private", false); repo1.put("description", "A sample repo for Android testing"); repo1.put("language", "Java"); repo1.put("forks_count", 10); repo1.put("open_issues", 2); repo1.put("watchers", 45); // Second repository entry JSONObject repo2 = new JSONObject(); repo2.put("name", "kotlin-utils"); repo2.put("private", true); repo2.put("description", "Utility functions for Kotlin projects"); repo2.put("language", "Kotlin"); repo2.put("forks_count", 25); repo2.put("open_issues", 5); repo2.put("watchers", 120); items.put(repo1); items.put(repo2); response.put("items", items); return response; }
1.2 Invalid Sample JSON (Missing "items" Field)
This will trigger the JSONException your function throws when the required field is absent:
private JSONObject createInvalidResponseJson() throws JSONException { JSONObject response = new JSONObject(); response.put("message", "Request failed"); response.put("status", 404); // Intentionally omit the "items" field to trigger the error return response; }
Let's use JUnit (4 or 5) for testing. If your parsing function lives in a class like GithubResponseParser, here's how your test class would look:
import org.junit.Test; import org.junit.Assert; import org.json.JSONException; import org.json.JSONObject; import java.util.List; public class GithubResponseParserTest { // Initialize your parser class private final GithubResponseParser parser = new GithubResponseParser(); @Test public void parseAndReturnGithubRepositorySearchResponse_validJson_returnsCorrectRepoList() throws Exception { // Arrange: Prepare valid JSON input JSONObject validJson = createValidResponseJson(); // Act: Run the parsing function List<GithubRepositorySchema> result = parser.parseAndReturnGithubRepositorySearchResponse(validJson); // Assert: Verify the output matches expectations Assert.assertEquals(2, result.size()); // Validate first repository details GithubRepositorySchema firstRepo = result.get(0); Assert.assertEquals("android-test-sample", firstRepo.getName()); Assert.assertEquals(false, firstRepo.isPrivate()); Assert.assertEquals("A sample repo for Android testing", firstRepo.getDescription()); Assert.assertEquals("Java", firstRepo.getLanguage()); Assert.assertEquals(10, firstRepo.getForksCount()); Assert.assertEquals(2, firstRepo.getOpenIssues()); Assert.assertEquals(45, firstRepo.getWatchers()); // Validate second repository details GithubRepositorySchema secondRepo = result.get(1); Assert.assertEquals("kotlin-utils", secondRepo.getName()); Assert.assertEquals(true, secondRepo.isPrivate()); } // JUnit 4 style: Expect JSONException for invalid input @Test(expected = JSONException.class) public void parseAndReturnGithubRepositorySearchResponse_invalidJson_throwsJSONException() throws Exception { // Arrange: Prepare invalid JSON input JSONObject invalidJson = createInvalidResponseJson(); // Act: Run the parsing function (should throw exception) parser.parseAndReturnGithubRepositorySearchResponse(invalidJson); } // JUnit 5 style alternative for exception testing (more flexible) /* @Test void parseAndReturnGithubRepositorySearchResponse_invalidJson_throwsJSONException() throws Exception { JSONObject invalidJson = createInvalidResponseJson(); Assertions.assertThrows(JSONException.class, () -> { parser.parseAndReturnGithubRepositorySearchResponse(invalidJson); }); } */ // Include the createValidResponseJson and createInvalidResponseJson methods here private JSONObject createValidResponseJson() throws JSONException { // Implementation from section 1.1 } private JSONObject createInvalidResponseJson() throws JSONException { // Implementation from section 1.2 } }
If you need to mock JSONObject (e.g., for isolated testing without real Android JSON classes), use Mockito to simulate its behavior. Here's how to mock valid and invalid scenarios:
import org.junit.Test; import org.junit.Assert; import org.mockito.Mockito; import org.json.JSONException; import org.json.JSONObject; import org.json.JSONArray; import java.util.List; public class GithubResponseParserMockTest { private final GithubResponseParser parser = new GithubResponseParser(); @Test public void parseAndReturnGithubRepositorySearchResponse_mockedValidJson_returnsCorrectList() throws Exception { // Arrange: Mock all required JSON objects JSONObject mockedResponse = Mockito.mock(JSONObject.class); JSONArray mockedItems = Mockito.mock(JSONArray.class); JSONObject mockedRepo = Mockito.mock(JSONObject.class); // Mock behavior for valid response Mockito.when(mockedResponse.has("items")).thenReturn(true); Mockito.when(mockedResponse.getJSONArray("items")).thenReturn(mockedItems); Mockito.when(mockedItems.length()).thenReturn(1); Mockito.when(mockedItems.getJSONObject(0)).thenReturn(mockedRepo); // Mock repository field values Mockito.when(mockedRepo.getString("name")).thenReturn("mocked-test-repo"); Mockito.when(mockedRepo.getBoolean("private")).thenReturn(false); Mockito.when(mockedRepo.getString("description")).thenReturn("A mocked repository"); Mockito.when(mockedRepo.getString("language")).thenReturn("Java"); Mockito.when(mockedRepo.getInt("forks_count")).thenReturn(5); Mockito.when(mockedRepo.getInt("open_issues")).thenReturn(1); Mockito.when(mockedRepo.getInt("watchers")).thenReturn(20); // Act List<GithubRepositorySchema> result = parser.parseAndReturnGithubRepositorySearchResponse(mockedResponse); // Assert Assert.assertEquals(1, result.size()); Assert.assertEquals("mocked-test-repo", result.get(0).getName()); } @Test(expected = JSONException.class) public void parseAndReturnGithubRepositorySearchResponse_mockedInvalidJson_throwsException() throws Exception { JSONObject mockedResponse = Mockito.mock(JSONObject.class); // Mock missing "items" field Mockito.when(mockedResponse.has("items")).thenReturn(false); parser.parseAndReturnGithubRepositorySearchResponse(mockedResponse); } }
内容的提问来源于stack exchange,提问作者Samyak

