Home > database >  Can anyone suggest a mockito Test for this code?
Can anyone suggest a mockito Test for this code?

Time:11-13

This function tries to retrieve the topic of the GitHub repository name using the GitHub API: https://api.github.com/repos/flutter/flutter/topics

public List<String> getTopics(String user, String repo){
    GitHubRequest request = new GitHubRequest();
    List<String> topic_list = new ArrayList<>();
    try {
        Repository repository = repositoryService.getRepository(user,repo);
        String url =  repository.getUrl().split("//")[1].split("api.github.com")[1];
        request.setUri(url   "/topics");
        String result = new BufferedReader(new InputStreamReader(gitHubClient.getStream(request)))
                .lines().collect(Collectors.joining("\n"));
        JSONObject jsonObject = new JSONObject(result);
        topic_list = Arrays.stream(jsonObject.get("names").toString().replace("[", "").replace("]", "").split(",")).collect(Collectors.toList());
    } catch (IOException e) {
        e.printStackTrace();
    }
    return topic_list;
}

Is there a way to write a mockito test case for this? A beginner to testing, so thank you!

CodePudding user response:

First, you need to inject the mock object (repositoryService,gitHubClient) to your function.

If you use spring/spring boot, you can consider to use @Mock and @MockBean annotation. to mock the necessary bean.

The below code to create mock object manually.

RepositoryService fakeRs = Mockito.mock(RepositoryService.class);
GitHubClient fakeGHC = Mockito.mock(GitHubClient.class);

You also can use setter method to set mock object. setRepositoryService(fakeRs); setGitHubClient(fakeGHC);

The other way is using reflection utility to set private object.

ReflectionTestUtils.setField(yourService, "repositoryService", fakeRs);
ReflectionTestUtils.setField(yourService, "gitHubClient", fakeGHC);

After finish ingesting the mock object, you can write an test with expected behavior/data from mock object.

    @Test
    public void testGetTopics(){
       // init mock object code in case setter/getter/reflection utils
       Repository expectedRepository = createExampleRepository();
Mockito.when(repositoryService.getRepository(Mockito.anyString(),Mockito.anyString())
.thenReturn(expectedRepository);

     // continue to fake gitHubClient with your expected data/ exceptions...
    //call your method
    List<?> data = yourService.getTopic("user","data");
    Assertions.assertTrue(data!=null); 
   // you can write few assertion base on your fake datas
    }

PS: Don't copy/paste the code, you will get compile errors. I am not using editor tool.

CodePudding user response:

You can mock repositoryService and gitHubClient to test various scenarios.

You can provide a package-level setter for these fields. It is a great idea to annotate it with Guava VisibleForTesting annotation.

Then you need to set mocks before the actual test on the instance.

Pseudocode for mocking

// First, we mock repository so we can return it from service
Repository repositoryMock = mock(Repository.class);
when(repository.getUrl()).thenReturn("https://...."); // You can return a URL or String, according to the mocked method's return type

// Then, we mock RepositoryService as well
RepositoryService repositoryServiceMock = mock(RepositoryService.class);
when(repositoryServiceMock.getRepository(anyString(), anyString()).thenReturn(repositoryMock);

// We mock gitHubService similarly
...

// After setting mock on the instance, we call the method and see if the results are expected
List<String> topics = getTopics("...", "...");

assertEquals(topics, ...);

// You can also assert interaction related things
verify(repositoryService).getRepository("a", "b"); // This is OK only if the service is called with "a" and "b" arguments
  • Related