Как издеваться над resttemplate от mockito

Я хочу издеваться над запросом 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 реализует интерфейс RestOperations специально, чтобы облегчить насмешки.

chrylis -cautiouslyoptimistic- 30.05.2019 05:42
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
1
1
1 136
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Вам нужно передать экземпляр 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. Установленное возвращаемое значение недействительно.

Kepler 30.05.2019 07:28

Хорошо, теперь в этом случае используется макет, вероятно, один из сопоставителей в вашем 'mockito.when()' не совпадает, возможно, попробуйте заменить eqs любым и посмотреть, работает ли это

Ryan M 30.05.2019 16:30

Я нашел решение и ответил на него ниже вопроса. Еще раз спасибо за вашу помощь :)

Kepler 31.05.2019 05:01
Ответ принят как подходящий

Я нашел решение. Когда нам нужно имитировать объект, созданный 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);
        //......
    }
}

Спасибо всем друзьям, которые помогли мне.

Другие вопросы по теме