Вот мое решение этой проблемы, но оно требует некоторых изменений.
Прежде всего, вы должны экстернализовать RestTemplate
как компонент и добавить преобразователи в его инициализацию. Таким образом вы избавитесь от того, чтобы не покрывать эти конвертеры.
@Bean
public RestTemplate restTemplate() {
RestTemplate restTemplate = new RestTemplate();
MappingJackson2HttpMessageConverter jsonConverter = new MappingJackson2HttpMessageConverter();
restTemplate.getMessageConverters().add(jsonConverter);
StringHttpMessageConverter stringConverter = new StringHttpMessageConverter();
restTemplate.getMessageConverters().add(stringConverter);
return restTemplate;
}
Вот новый класс, содержащий метод postJson
. Как видите, url
и restTemplate
вводятся через конструктор. Таким образом, мы можем тестировать разные случаи.
public class Poster {
private RestTemplate restTemplate;
private String url;
public Poster(RestTemplate restTemplate, String url) {
this.restTemplate = restTemplate;
this.url = url;
}
public void postJson(Set<Type> types) {
try {
String oneString = types.stream().map(Type::toString).collect(Collectors.joining(","));
Map<String, String> requestBody = new HashMap<>();
requestBody.put("type", oneString);
requestBody.put("data", "aws");
JSONObject jsonObject = new JSONObject(requestBody);
HttpEntity<String> request = new HttpEntity<>(jsonObject.toString(), null);
ResponseEntity<String> result = restTemplate
.postForEntity(url, new HttpEntity<>(request, getHttpHeaders()), String.class);
int code = result.getStatusCodeValue();
} catch (Exception ignored) {}
}
private HttpHeaders getHttpHeaders() {
return new HttpHeaders();
}
}
А вот и тестовый класс для этого метода.
class PosterTest {
@Mock
private RestTemplate restTemplate;
private String url;
private Poster poster;
@BeforeEach
public void setUp() {
MockitoAnnotations.initMocks(this);
this.url = "http://example.com/posturl";
this.poster = new Poster(restTemplate, url);
}
@Test
void postJson() {
// set input, I used TreeSet just to have a sorted set
// so that I can check the results against
Set<Type> types = new TreeSet<>(Comparator.comparing(Type::toString));
types.add(new Type("a"));
types.add(new Type("b"));
types.add(new Type("c"));
types.add(new Type("d"));
// response entity
ResponseEntity<String> response = ResponseEntity.ok("RESPONSE");
// mockito mock
Mockito.when(restTemplate.postForEntity(
ArgumentMatchers.eq(url),
ArgumentMatchers.any(HttpHeaders.class),
ArgumentMatchers.eq(String.class)
)).thenReturn(response);
// to check the results
Map<String, String> requestBody = new HashMap<>();
requestBody.put("type", "a,b,c,d");
requestBody.put("data", "aws");
JSONObject jsonObject = new JSONObject(requestBody);
HttpEntity<String> request = new HttpEntity<>(jsonObject.toString(), null);
HttpEntity<HttpEntity<String>> httpEntity = new HttpEntity<>(request, new HttpHeaders());
// actual call
poster.postJson(types);
// verification
Mockito.verify(restTemplate, times(1)).postForEntity(
ArgumentMatchers.eq(url),
ArgumentMatchers.eq(httpEntity),
ArgumentMatchers.eq(String.class));
}
}
Лучше иметь такие зависимости, как RestTemplate
или другие ServiceClass
Это так, чтобы их можно было легко проверять и проверять.