Интеграционный тест с Spring Boot и Spock
каков наилучший способ запуска интеграционного теста (например,@IntegrationTest
) С Спок? Я хотел бы загрузить все приложение Spring Boot и выполнить некоторые HTTP-вызовы для проверки всей функциональности.
Я могу сделать это с помощью JUnit (сначала запускается приложение, а затем выполняются тесты):
@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = MyServer.class)
@WebAppConfiguration
@IntegrationTest
class MyTest {
RestTemplate template = new TestRestTemplate();
@Test
public void testDataRoutingWebSocketToHttp() {
def a = template.getForEntity("http://localhost:8080", String.class)
println a
}
}
но с Spock приложение не запускается:
@SpringApplicationConfiguration(classes = MyServer.class)
@WebAppConfiguration
@IntegrationTest
class MyTestSpec extends Specification {
RestTemplate template = new TestRestTemplate();
def "Do my test"() {
setup:
def a = template.getForEntity("http://localhost:8080", String.class)
expect:
println a
}
}
для Spock, конечно, я указал правильные зависимости в моей сборке Gradle файл:
...
dependencies {
testCompile 'org.spockframework:spock-core:0.7-groovy-2.0'
testCompile 'org.spockframework:spock-spring:0.7-groovy-2.0'
}
...
Я что-то пропустила?
4 ответов
проблема в том, что Спок Спринг ищет весну @ContextConfiguration
аннотация и не удается ее найти. Строго говоря MyTestSpec
и аннотируется @ContextConfiguration
как это мета-аннотации @SpringApplicationConfiguration
но Спок Спринг не рассматривает мета-аннотации как часть своего поиска. Есть вопрос для решения этого ограничения. А пока ты можешь обойти это.
все это @SpringApplicationConfiguration
делает это настройка @ContextConfiguration
С загрузкой загрузчик контекста. Это означает, что вы можете достичь того же эффекта с помощью правильно настроенный аннотация:
@ContextConfiguration(loader = SpringApplicationContextLoader.class, classes = MyServer.class)
@WebAppConfiguration
@IntegrationTest
class MyTestSpec extends Specification {
…
}
обновление: просто чтобы убедиться ,что это ясно (и на основе комментариев, это не было), для этого вам нужно иметь org.spockframework:spock-spring
на пути к классу.
в идеале вы будете использовать Spring Boot 1.4+ и Spock 1.1+.
Spring Boot добавил много полезных аннотаций. В дополнение к этому @SpringBootTest
это @ignacio.Суай упомянул, они также добавили @TestConfiguration
что полезно, если вы хотите использовать Spring mocks в своих интеграционных тестах вместо Mockito.
если вы объедините @TestConfiguration
С Новым Споком DetachedMockFactory
, тогда у вас есть все компоненты, которые вам понадобятся, чтобы ввести Spock Mocks в ваш весенний контекст.
Я сообщение в блоге с примером кода здесь:весеннее интеграционное тестирование с помощью Spock Mocks.
быстрый и грязный это
@SpringBootTest
class MyIntegrationTest extends Specification {
@Autowired ExternalRankingService externalRankingServiceMock
def "GetRank"() {
when:
classUnderTest.getRankFor('Bob')
then:
1 * externalRankingServiceMock.fetchRank('Bob') >> 5
}
@TestConfiguration
static class Config {
private DetachedMockFactory factory = new DetachedMockFactory()
@Bean
ExternalRankingService externalRankingService() {
factory.Mock(ExternalRankingService)
}
}
}
обновление
Есть пиар чтобы получить более родную поддержку в Spock для инъекции Spock Mocks в весенний контекст для интеграционного тестирования. Новый @SpringBean
и @SpringSpy
как бы @MockBean
и @SpyBean
аннотации
обновление Спок 1.2 теперь внесенные изменения. Пока документация не будет обновлена, вот предварительный просмотр аннотаций Spock 1.2 для тестирования интеграции Spring .
в новой версии Spring Boot (1.4) вместо использования:
@SpringApplicationConfiguration(classes = MyServer.class)
@WebAppConfiguration
@IntegrationTest
можно использовать
@SpringBootTest(classes = MyServer.class)
и вы сможете запустить контекст приложения и установить любую зависимость.
для получения дополнительной информации, пожалуйста, взгляните на этот пример: http://ignaciosuay.com/how-to-do-integration-tests-with-spring-boot-and-spock/
вот настройка, которая запускает загрузочное приложение, а затем запускает тесты spock:
class HelloControllerSpec extends Specification {
@Shared
@AutoCleanup
ConfigurableApplicationContext context
void setupSpec() {
Future future = Executors
.newSingleThreadExecutor().submit(
new Callable() {
@Override
public ConfigurableApplicationContext call() throws Exception {
return (ConfigurableApplicationContext) SpringApplication
.run(Application.class)
}
})
context = future.get(60, TimeUnit.SECONDS)
}
void "should return pong from /ping"() {
when:
ResponseEntity entity = new RestTemplate().getForEntity("http://localhost:8080/ping", String.class)
then:
entity.statusCode == HttpStatus.OK
entity.body == 'pong'
}
}
и не забудьте добавить зависимости к spock и groovy внутри build.gradle
dependencies {
// other dependencies
testCompile "org.codehaus.groovy:groovy-all:2.2.0"
testCompile "org.spockframework:spock-core:0.7-groovy-2.0"
}