Невозможно автоматически подключить RestTemplate для модульного теста

avatar
comiventor
8 апреля 2018 в 07:56
7109
3
2

У меня есть служба, которая использует автосвязанный экземпляр RestTemplate, как показано ниже

.
@Service
class SomeAPIService {
    private RestTemplate restTemplate;

    SomeAPIService(RestTemplate restTemplate) {
        this.restTemplate = restTemplate;
        this.restTemplate.setRequestFactory(HttpUtils.getRequestFactory());
    }
}

В нетестовой среде все работает нормально. Но когда я пытаюсь запустить следующий модульный тест в тестовом профиле, он начинает жаловаться на невозможность автоматического подключения оставшегося шаблона.

@RunWith( SpringJUnit4ClassRunner.class )
@SpringBootTest(classes = MyApplication.class, webEnvironment = RANDOM_PORT, properties = "management.port:0")
@ActiveProfiles(profiles = "test")
@EmbeddedPostgresInstance(flywaySchema = "db/migration")
public abstract class BaseTest {
}

@SpringBootTest(classes = SomeAPIService.class)
public class SomeAPIServiceTest extends BaseTest {
    @Autowired
    SomeAPIService someAPIService;

    @Test
    public void querySomeAPI() throws Exception {
        String expected = someAPIService.someMethod("someStringParam");
    }
}

Ниже приводится подробное исключение -

Вызвано: org.springframework.beans.factory.UnsatisfiedDependencyException: Ошибка создания bean-компонента с именем «someAPIService»: неудовлетворенная зависимость выражается через параметр конструктора 0; вложенное исключение org.springframework.beans.factory.NoSuchBeanDefinitionException: Нет квалификационный компонент типа «org.springframework.web.client.RestTemplate» Доступно: ожидается по крайней мере 1 bean-компонент, который квалифицируется как autowire кандидат. Аннотации зависимостей: {}

Есть подсказки?

Источник

Ответы (3)

avatar
comiventor
9 апреля 2018 в 07:42
7

Следующее помогло мне автоматически установить правильные зависимости. Решение состоит в том, чтобы также включить RestTemplate.class в список классов, присвоенных SpringBootTest.

.
@SpringBootTest(classes = {RestTemplate.class, SomeAPIService.class})
class SomeAPIService {
    @Autowired
    SomeAPIService someAPIService;

    @Test
    public void querySomeAPI() throws Exception {
        String expected = someAPIService.someMethod("someStringParam");
    }
}

Ответ @Emre помог мне найти окончательное решение.

avatar
Saikat
17 марта 2020 в 12:00
0

Альтернативным ответом будет - использовать TestRestTemplate

Из официальных документов >>>

TestRestTemplate можно создать непосредственно в интеграционных тестах, как показано в следующем примере:

public class MyTest {

    private TestRestTemplate template = new TestRestTemplate();

    @Test
    public void testRequest() throws Exception {
        HttpHeaders headers = this.template.getForEntity(
                "https://myhost.example.com/example", String.class).getHeaders();
        assertThat(headers.getLocation()).hasHost("other.example.com");
    }

}

В качестве альтернативы, если вы используете аннотацию @SpringBootTest с WebEnvironment.RANDOM_PORT или WebEnvironment.DEFINED_PORT, вы можете внедрить полностью настроенный TestRestTemplate и начать использовать его. При необходимости дополнительные настройки можно применить с помощью bean-компонента RestTemplateBuilder.

avatar
Emre Savcı
8 апреля 2018 в 08:23
0

Вы пытаетесь автоматически подключить SomeAPIService, не удовлетворяя его зависимости. Вы должны внедрить Rest Template в SomeAPIService. Но вы получаете исключение NoSuchBeanDefinitionException для шаблона Rest.

Посмотрите, как его вводить:

Как автоматически связать RestTemplate с помощью аннотаций

comiventor
8 апреля 2018 в 08:36
0

У меня есть класс HttpConfiguration, аннотированный конфигурацией с определением bean-компонента для RestTemplate.

comiventor
8 апреля 2018 в 08:40
0

Кроме того, как я уже упоминал, мне трудно понять, почему все работает нормально в нетестовой среде, а в тестовой среде ломается. Я выполнял Autowiring таким образом, не вводя зависимости для других модульных тестов, и никогда не сталкивался с проблемой.

Emre Savcı
8 апреля 2018 в 09:12
1

Попробуйте изменить @SpringBootTest (classes = SomeAPIService.class) на @SpringBootTest (classes = MyApplication.class). Согласно документам весенней загрузки: «классы. Аннотированные классы для использования для загрузки ApplicationContext».

comiventor
9 апреля 2018 в 05:08
0

Спасибо, Эмре. Это было полезно и помогло мне решить проблему, но теперь активный профиль стал преследовать меня. Моему приложению требуется дополнительный активный профиль для создания определенных зависимостей. Я предоставляю активный профиль для теста maven, как этот mvn test -P myActiveProfile, но он дает мне ту же ошибку, что и при отказе от указания myActiveProfile в обычном запуске. проблема с проводкой, но другого рода

comiventor
9 апреля 2018 в 07:40
0

Использование @SpringBootTest(classes = MyApplication.class) фактически запускало все приложение, но не модульный тест.