Home > Blockchain >  Spring boot mock method response
Spring boot mock method response

Time:08-20

I need some help with unit tests. Our company has decided to start using TDD, and I'm supposed to implement that, but I've got very limited experience with unit tests in general, so I'm trying to cover some of the old code to get up to speed. That's when I got stuck with this:

public Analytics generateAnalytics(String id, String domain) {
    List<Result> totalResults = new ArrayList<>();

    for(String url : ANALYTIC_URLS) {
        url  = domain;
        String scrubbedUrl = url.replace(API_KEY, "XXXXXXXXXX");
        Audit audit = new Audit(id, scrubbedUrl);

        try {
            totalResults.add(new Result(getData(url, audit)));
        } catch(Exception e) {
            audit.setResponse(e.toString());
            throw new Exception(e);
        } finally {
            auditRepository.save(audit);
        }
    }

    return composeAnalytics(totalResults);
}

private List<Map<String, String>> getData(String request, Audit audit) throws Exception {
    try (CloseableHttpClient client = HttpClients.createDefault()) {
        CloseableHttpResponse response = client.execute(new HttpGet(request));

        if(response.getStatusLine().getStatusCode() == 200) {
            return readInputStream(response.getEntity().getContent(), audit);
        } else {
            throw new Exception(response.toString());
        }
    }
}

My issue is, when I wanna test the generateAnalytics method, the getData method goes and gets data from a live API that costs units per each request. Obviously I wanna stop this from bleeding out all our units during the testing. I've tried mocking the ClosableHttpClient like so:

@Mock
CloseableHttpClient client;

@InjectMocks
Service service;

@Test
void testTest() throws Exception {
    when(client.execute(any())).thenReturn(mock(CloseableHttpResponse.class));
    
    service.generateAnalytics("123", "no.com");
    assertEquals(true, true);
}

This works when there's another service that needs to be mocked in one of my other tests, but in this case it still calls the API and drains our units. What should I do about this?

CodePudding user response:

Have you try to use MockMvc?

With MockMvc you can perform requests against a mocked servlet environment. There won't be any real HTTP communication for such tests.

Official documentation: spring.io/testing-web

CodePudding user response:

That's because your client mock is never used:

try (CloseableHttpClient client = HttpClients.createDefault()) {

Either mock HttpClients.createDefault() or , maybe better, inject the client into the service instead of creating on the fly.

  • Related