#java #unit-testing #junit #mockito
#java #модульное тестирование #junit #mockito
Вопрос:
Component
public class MyService {
private final ObjectMapper objectMapper = new ObjectMapper();
private final RestTemplate restTemplate = new RestTemplate();
public void myMethod(){
------- codes to test above it------
HttpEntity<String> httpEntity = new HttpEntity<>(objectMapper
.writeValueAsString(message), httpHeaders);
String response = restTemplate
.postForObject(getUrl(), httpEntity, String.class);
}
}
Я пробовал @Spy, но он не работает
@InjectMocks
private MyService myService;
@Spy
private RestTemplate restTemplate;
when(restTemplate.postForObject(
getUrl(),
httpEntity,
String.class
)).thenReturn(getResponse());
Комментарии:
1. Неужели это весна?
2. Вы можете написать защищенный конструктор для MyService, который принимает параметр RestTemplate.
3. Да, это весной
Ответ №1:
Если вы хотите шпионить:
@Test
void test(){
MyService myService = Mockito.spy(MyService.class);
myService.myMethod();
}
Таким образом, вы получаете экземпляр RestTemplate.
Лично я предпочитаю получать RestTemplate в качестве зависимости, которая позволяет легко издеваться.
например:
private final RestTemplate restTemplate;
public MyService(RestTemplate restTemplate) {
this.restTemplate = restTemplate;
}
И в вашем тесте
//@RunWith(MockitoJUnitRunner.class) //junit4
@ExtendWith(MockitoExtension.class) //junit 5
public class MyServiceTest {
@Mock
private RestTemplate restTemplate;
@InjectMocks
private MyService myService;
@Test
void test(){
when(restTemplate.postForObject(
getUrl(),
httpEntity,
String.class
)).thenReturn(getResponse());
//do whatever you like
}
}
Комментарии:
1. Я хочу издеваться над методом postForObject, а не вызывать фактический метод
2. Вы пытаетесь протестировать myMethod(), не так ли?
3. о, пропустил деталь, я хочу протестировать приведенный выше код, чтобы он не вызывал фактический http-вызов, отредактировал мой код