Есть микросервис, созданный с помощью Spring Boot. Он состоит из причалов, Джерси, Джексон и Ликвибасе. Одна из задач этой службы - получить какие-то данные через REST и вернуть ответ. Эта операция проходит через следующие блоки:

  • MyResource, @Component REST с аннотациями JAX-RS, который получает данные и запрашивает ответ у @Autowired MyService.
  • MyService, @Component сервис с @Autowired MyResource, чтобы запросить ответ.
  • MyResource, простой @JpaRepository интерфейс

Это приложение работает нормально, но теперь мне нужно добавить несколько тестов для каждого модуля. Обычно я использую Mockito для тестирования модулей, поэтому я тестирую свой сервис с помощью mocked MyRepository (аннотация Mockito @Mock + метод when ()). Я хочу таким же образом протестировать MyResource.java.

Я попытался использовать способ TestRestTemplate для тестирования с помощью spring-boot-starter-test, и мой тестовый класс выглядит так:

@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = Application.class)
@WebIntegrationTest(randomPort = true)
public class MyResourceTest {
  @Value("${local.server.port}")
  private int port;

  private String getBaseUrl() {
    return "http://localhost:" + port;
  }

  @Test
  public void test() {
    final TestRestTemplate restTemplate = new TestRestTemplate();
    assertEquals(restTemplate.postForEntity(getBaseUrl() + "/test", null, ResponseObject.class).getBody(), new ResponseObject());
  }
}

И есть две проблемы. Во-первых, когда мой тест запущен, они запускают все весеннее приложение, поэтому мои скрипты Liquibase пытаются найти базу данных, а это очень долгий процесс. Во-вторых, я не могу заменить класс MyService прокси Mockito.

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

0
finnetrolle 24 Фев 2016 в 17:11

2 ответа

Лучший ответ

MockMvc - предпочтительное решение вашей проблемы. Он запускает приложение весенней загрузки, но «издевается» над запросом, поэтому на самом деле он не запускается через http, а ведет себя соответствующим образом. Вы можете внедрить все bean-компоненты вашего приложения в тестовый класс с помощью @Autowired, чтобы там можно было имитировать Spring beans.

2
Stefan Isele - prefabware.com 24 Фев 2016 в 21:37

Я провожу все свои тесты по 6 классам конфигурации / поддержки.

AbstractTest для настройки ядра тестов

@ActiveProfiles(resolver = TestActiveProfilesResolver.class)
@RunWith(SpringJUnit4ClassRunner.class)
@WebAppConfiguration
@IntegrationTest
@SpringApplicationConfiguration(classes = Application.class)
public abstract class AbstractTest {
   ...
}

AbstractRepositoryTest для тестирования моих репозиториев через jdbc + jdbi

@Transactional
public abstract class AbstractRepositoryTest<R> extends AbstractTest implements Repositories {

    @Inject
    private ObjectMapper mapper;

    @Inject
    protected Repositories repositories;

    private final Class<R> repositoryType;

    ...
}

AbstractServiceTest для тестирования моих сервисов, этот класс содержит ядро моего теста сервиса

public abstract class AbstractServiceTest {
    ...
}

AbstractIntegrationTest содержит ядро моих интеграционных тестов, использует методы для тестирования контроллера и т. д.

public abstract class AbstractIntegrationTest extends AbstractTest {
    ...
}

Приложение предоставляет AbstractTest контекст для запуска тестов, этот класс - тот же класс, который я использую для запуска моего приложения весенней загрузки

@SpringBootApplication
public class Application extends SpringBootServletInitializer {
    public static void main(final String[] args) {
        SpringApplication.run(Application.class, args);
    }

    @Override
    protected SpringApplicationBuilder configure(final SpringApplicationBuilder application) {
        return application.sources(Application.class);
    }
    ...
}

И наконец, выберите TestActiveProfilesResolver , который предоставляет профиль для соответствия application-test.properties. Это необходимо, потому что существует открытая проблема в JIRA, здесь

public class TestActiveProfilesResolver implements ActiveProfilesResolver {

    @Override
    public String[] resolve(final Class<?> testClass) {
        final String activeProfile = System.getProperty("spring.profiles.active");
        return new String[] {activeProfile == null ? "test" : activeProfile};
    }

}

Иногда мои тесты расширяют AbstractRepositoryTest, AbstractIntegrationTests или AbstractServiceTest, это зависит от того, что я хочу. Эта конфигурация решила все мои проблемы с тестированием служб , контроллеров и т. Д.

1
Rafael Eyng 17 Июн 2016 в 17:44