Я хочу издеваться над запросом resttemplate, но, похоже, это не работает. Вот класс, который я хочу проверить:
public class SomeUtil {
public static OrderInstanceResponse doGet(String url, otherargs...) {
//some code...
ResponseEntity<String> responseEntity = restTemplate.exchange(url, HttpMethod.GET, requestHeader, String.class, requestMap);
//another code...
}
}
Вот тестовый класс:
@RunWith(MockitoJUnitRunner.class)
public class SomeUtilTest {
@Mock
private RestTemplate restTemplate;
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
}
@Test
public void doGet() {
OrderInstanceResponse exceptResponse = OrderInstanceResponse.builder().code("123").build();
OrderInstanceRequest request = OrderInstanceRequest.builder().userId("123").build();
Map<String, Object> testMap = new HashMap<>(1);
testMap.put("userId", "123");
Mockito.when(restTemplate.exchange(Mockito.anyString(), Mockito.any(), Mockito.any(), Mockito.eq(String.class), Mockito.eq(testMap)))
.thenReturn(new ResponseEntity<>("\"code\":\"123\"", HttpStatus.OK));
OrderInstanceResponse actualResponse = RestTemplateUtil.doGet("123", request, "123");
Assert.assertEquals(actualResponse.getCode(), exceptResponse.getCode());
}
}
При запуске этого теста есть некоторые ошибки:
java.lang.IllegalArgumentException: URI is not absolute
.
Похоже, макет не работает, был реальный запрос на "123".
Как я могу исправить эту ошибку? спасибо
Вам нужно передать экземпляр RestTemplate
в RestTemplateUtil в качестве зависимости, чтобы это работало, а не создавать его экземпляр в методе doGet
. Затем в модульном тесте передайте фиктивный экземпляр RestTemplate
в RestTemplateUtil.
public class SomeUtil {
public SomeUtil(RestTemplate restTemplate) { this.restTemplate = restTemplate }
public OrderInstanceResponse doGet(String url, otherargs...) {
ResponseEntity<String> responseEntity = this.restTemplate.exchange(...
}
}
Или передайте RestTemplate в качестве параметра, если вы хотите сохранить его как статический метод.
Спасибо за вашу помощь. Я пробовал по-вашему, но это все равно не сработало. Я имитирую resttemplate вот так RestTemplate restTemplate = Mockito.mock(RestTemplate.class);
и передаю RestTemplate в качестве параметра doGet(RestTemplate rest, String url, ...)
. Больше нет ошибок URI is not absolute
, но responseEntity равен NULL. Установленное возвращаемое значение недействительно.
Хорошо, теперь в этом случае используется макет, вероятно, один из сопоставителей в вашем 'mockito.when()' не совпадает, возможно, попробуйте заменить eqs любым и посмотреть, работает ли это
Я нашел решение и ответил на него ниже вопроса. Еще раз спасибо за вашу помощь :)
Я нашел решение.
Когда нам нужно имитировать объект, созданный new
, например RestTemplate rest = new RestTemplate()
, следует писать так:
PowerMockito.whenNew(ObjectToBeMocked.class).withAnyArguments().thenReturn(mockedObject);
Затем добавьте аннотацию @PrepareForTest({TheClassToBeTested.class})
. Обратите внимание, параметр — это класс, содержащий объект, полученный с помощью new
.
Итак, полный код выглядит следующим образом:
@RunWith(MockitoJUnitRunner.class)
@PrepareForTest({SomeUtil.class})
public class SomeUtilTest {
@Mock
private RestTemplate restTemplate;
@Test
public void doGet() {
//......
PowerMockito.whenNew(RestTemplate.class).withAnyArguments().thenReturn(restTemplate);
//......
}
}
Спасибо всем друзьям, которые помогли мне.
Кстати,
RestTemplate
реализует интерфейсRestOperations
специально, чтобы облегчить насмешки.