#java #spring-boot #junit #mockito #resttemplate
Вопрос:
Мой текущий модульный тест, использующий RestTemplate для достижения конечной точки GET, содержит множество жестко закодированных значений. Я хотел бы знать, есть ли лучший подход, высмеивающий ценности, и как это сделать. В настоящее время это выглядит так:
@RunWith(MockitoJUnitRunner.class)
public class CarServiceTest {
private final String uri = "https://cars.com/cars";
private final String token = "xxx";
private List<Car> carList;
private Cars testCars;
@Mock
private RestTemplate restTemplate;
@InjectMocks
private CarService carService;
@BeforeAll
void init() {
carList = new ArrayList<>(Arrays.asList(new Car("car1")));
testCars = new Cars(carList);
}
@Test
public void test_getCars() {
HttpHeaders headers = new HttpHeaders();
headers.setBearerAuth(token);
headers.setAccept(List.of(MediaType.APPLICATION_JSON));
Mockito.when(restTemplate.exchange(
RequestEntity.get(new URI(uri)).headers(headers).build(),
Cars.class))
.thenReturn(new ResponseEntity(testCars, HttpStatus.OK));
Cars returnedCars = carService.getCars();
// assertion
Assert.assertEquals(testCars, returnedCars);
// verify
verify(restTemplate).exchange(RequestEntity
.get(new URI(uri)).headers(headers).build(),
Cars.class);
verifyNoMoreInteractions(restTemplate);
}
}
Я ищу предложения о том, как улучшить инициализацию/издевательство над объектами, используемыми в тесте. (В настоящее время я использую реальный URL-адрес и токен в тестах)
Ответ №1:
Вы можете использовать сервер MockRestServiceServer.
RestTemplate restTemplate = new RestTemplate();
MockRestServiceServer server = MockRestServiceServer.bindTo(restTemplate).build();
server.expect(MockRestRequestMatchers.requestTo(uri))
.andExpect(requestTo(uri))
.andExpect(method(HttpMethod.GET))
.andRespond(withSuccess(new ObjectMapper()
.writeValueAsString(cars), MediaType.APPLICATION_JSON));
HttpHeaders headers = new HttpHeaders();
headers.setBearerAuth(token);
headers.setAccept(List.of(MediaType.APPLICATION_JSON));
restTemplate.exchange(RequestEntity.get(new URI(uri)).headers(headers).build(), Cars.class))
server.verify();
Вы можете настроить заглушку, которая вам нужна, а также убедиться, что вызовы, которые вы ожидали, действительно произошли в нескольких строках кода и намного более понятны ИМО.
Комментарии:
1. Какие аннотации вам нужно использовать при объявлении переменных?
2. Это полностью зависит от вашей тестовой среды , но если вы говорите о таких аннотациях, как
@Mock
, например, они вам больше не нужны, так как spring выполняет всю обработку и проверку для вас. Вы можете прочитать документацию, связанную с ответом, чтобы узнать больше.