Модульное тестирование Mockito для шаблона отдыха - PullRequest
0 голосов
/ 28 октября 2019

Я пытаюсь написать модульный тест для шаблона отдыха, который выполняет http-вызовы. Я создал шаблон отдыха с помощью компоновщика остальных шаблонов, как показано ниже. шаблон остальных настроен для настройки таймаутов чтения и подключения. У меня также есть шаблон повторов, который должен выполнять повторные попытки, когда приложение имеет тайм-аут. Я нахожусь в точке, где я указал методы http: postForEntity, exchange и getForEntity, которые необходимо повторить в шаблоне повторов и нуждаются в помощи при написании модульных тестов. Я начал с метода getForEntity, но получаю результат, отличный от ожидаемого. любая помощь с этим была бы полезна.

Шаблон отдыха

 @Bean
public RestTemplate restTemplate() {
    return new RestTemplateBuilder()
            .setConnectTimeout(Duration.ofSeconds(10))
            .setReadTimeout(Duration.ofSeconds(10))
            .build();

}

Повторная попытка getForEntity

 public ResponseEntity getForEntity(URI uri, Class c) {
    return retryTemplate.execute(retryContext -> {
        return restTemplate.getForEntity(uri, c);
    });
}

Модульный тест

public class RetryRestTemplateTest {

@Mock
private RestTemplate restTemplate;

@Mock
private RetryTemplate retryTemplate;

private RetryRestTemplate retryRestTemplate;

String testUrl = "http://localhost:8080";

@Before
public void setup() {
    MockitoAnnotations.initMocks(this);

    retryRestTemplate = new RetryRestTemplate(
            restTemplate,
            retryTemplate
    );
}

@Test
public void getForEntity() throws URISyntaxException{
    URI testUri= new URI(testUrl);
    ArgumentCaptor<URI> argument = ArgumentCaptor.forClass(URI.class);

    doReturn(new ResponseEntity<>("ResponseString", HttpStatus.OK))
            .when(restTemplate).getForEntity(any(URI.class), eq(String.class));

    assertThat(restTemplate.getForEntity(testUri, String.class), is(HttpStatus.OK));

    verify(restTemplate).getForEntity(argument.capture(), eq(String.class));
    assertThat(argument.getValue().toString(), is(testUri));
}}

Мое ожидаемое значение должно быть <200 OK>, а мое фактическое значение - <200 OK OK, ResponseString, [] >>

Любая помощь по этому вопросу будет полезна, так как я не настолько опытен с Mockitoи джунит.

1 Ответ

0 голосов
/ 28 октября 2019

Ваши ожидания не совпадают с кодом, который вы написали getForEntity не возвращает HttpStatus экземпляр, вместо этого он возвращает ResponseEntity<String>. Сравнение ResponseEntity<String> с HttpStatus никогда не даст равных.

Фиксированная версия вашего теста:

  @Test
  public void getForEntity() throws URISyntaxException {
    URI testUri = new URI(testUrl);
    ArgumentCaptor<URI> argument = ArgumentCaptor.forClass(URI.class);

    doReturn(new ResponseEntity<>("ResponseString", HttpStatus.OK))
        .when(restTemplate).getForEntity(any(URI.class), eq(String.class));

    assertThat(restTemplate.getForEntity(testUri, String.class).getStatusCode(),
        CoreMatchers.is(HttpStatus.OK));

    verify(restTemplate).getForEntity(argument.capture(), eq(String.class));
    assertThat(argument.getValue(), CoreMatchers.is(testUri));
  }

Примечание: тест на самом деле не тестирует getForEntity, он проверяет, что java-прокси, созданный с помощью mockito, возвращает поддельный результат. Imho, вы на самом деле тестируете, работает ли фиктивная инфраструктура ...

doReturn(new ResponseEntity<>("ResponseString", HttpStatus.OK)).when(restTemplate).getForEntity(any(URI.class), eq(String.class));

Как обсуждалось в комментариях, интеграционный тест RestTemplate может быть:

package com.example.demo;

import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.MatcherAssert.assertThat;

import java.io.IOException;
import java.net.URI;
import okhttp3.mockwebserver.MockResponse;
import okhttp3.mockwebserver.MockWebServer;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.client.RestTemplate;

public class RetryRestTemplateTest {

  private final MockWebServer server = new MockWebServer();

  @BeforeEach
  public void setup() throws IOException {
    server.start();
  }

  @AfterEach
  public void teardown() throws IOException {
    server.close();
  }

  @Test
  public void getForEntity() {
    URI testUri = server.url("/").uri();
    server.enqueue(new MockResponse().setResponseCode(200).setBody("{}"));

    RestTemplate restTemplate = new RestTemplate();

    ResponseEntity<String> forEntity = restTemplate.getForEntity(testUri, String.class);
    assertThat(forEntity.getStatusCode(), is(HttpStatus.OK));
    assertThat(forEntity.getBody(), is("{}"));
  }
}

Следующеенеобходимы тестовые зависимости:

<dependency>
  <groupId>com.squareup.okhttp3</groupId>
  <artifactId>mockwebserver</artifactId>
  <version>4.2.2</version>
  <scope>test</scope>
</dependency>
<dependency>
  <groupId>com.squareup.okhttp3</groupId>
  <artifactId>okhttp</artifactId>
  <version>4.2.2</version>
  <scope>test</scope>
</dependency>
...