Java 与Spring Boot和Spock的集成测试
使用Spock运行集成测试(例如)的最佳方式是什么?我想引导整个Spring引导应用程序,并执行一些HTTP调用来测试整个功能 我可以使用JUnit(首先运行应用程序,然后执行测试): 但使用Spock时,应用程序不会启动:Java 与Spring Boot和Spock的集成测试,java,groovy,gradle,spring-boot,spock,Java,Groovy,Gradle,Spring Boot,Spock,使用Spock运行集成测试(例如)的最佳方式是什么?我想引导整个Spring引导应用程序,并执行一些HTTP调用来测试整个功能 我可以使用JUnit(首先运行应用程序,然后执行测试): 但使用Spock时,应用程序不会启动: @SpringApplicationConfiguration(classes = MyServer.class) @WebAppConfiguration @IntegrationTest class MyTestSpec extends Specification {
@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'
}
...
我遗漏了什么吗?问题是Spock Spring正在查找Spring的
@ContextConfiguration
注释,但没有找到它。严格来说,<代码> MyTestStuts被注释为<代码> @ CONTXECUTION/<代码>,因为它是对<代码> @ SpringApplicationConfiguration >代码的元注释。但是Spock Spring不认为元注释是其搜索的一部分。有一种方法可以解决这个限制。与此同时,你可以解决这个问题
@SpringApplicationConfiguration
所做的就是使用特定于引导的上下文加载程序定制@ContextConfiguration
。这意味着您可以通过使用适当配置的@ContextConfiguration
注释来实现相同的效果:
@ContextConfiguration(loader=SpringApplicationContextLoader.class,classes=MyServer.class)
@WebAppConfiguration
@集成测试
类MyTestSpec扩展了规范{
…
}
更新:为了确保它的清晰性(根据评论,它不是),要让它工作,你需要在类路径上有
org.spockframework:spock spring
。在新的spring启动版本(1.4)中,而不是使用:
@SpringApplicationConfiguration(classes = MyServer.class)
@WebAppConfiguration
@IntegrationTest
你可以用
@SpringBootTest(classes = MyServer.class)
您将能够启动应用程序上下文并设置任何依赖项
有关更多信息,请查看以下示例:
理想情况下,您将使用Spring Boot 1.4+和Spock 1.1+ SpringBoot添加了很多有用的注释。除了@ignacio.suay提到的
@SpringBootTest
之外,他们还添加了@TestConfiguration
,如果您想在集成测试中使用Spring mock而不是Mockito,这非常有用
如果您将@TestConfiguration
与新的SpockDetachedMockFactory
相结合,那么您就拥有了将Spock Mock注入Spring上下文所需的所有组件
我有一篇博客文章,这里有示例代码:
这个又快又脏
@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模拟注入到Spring上下文中进行集成测试。新的@SpringBean
和@SpringSpy
类似于@MockBean
和@SpyBean
注释
更新
Spock1.2现在应该包括这些更改。在更新文档之前,这里是一个。这里是一个启动启动应用程序,然后运行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'
}
}
记住在build.gradle
dependencies {
// other dependencies
testCompile "org.codehaus.groovy:groovy-all:2.2.0"
testCompile "org.spockframework:spock-core:0.7-groovy-2.0"
}
有趣的是,我很确定我以前试过这个,但没用。。。但无论如何,谢谢!启动集成测试时是否有提供VM的标志?我已复制此配置,但我的应用程序未启动。我推断MyServer是具有配置和EnableAutoConfiguration注释的类对吗?不需要任何标志,您对MyServer的推断是正确的。您可以在此处阅读有关@ContextConfiguration的更多信息:。你在类路径上有spock spring吗?嗨@AndyWilkinson我刚回来告诉大家spock spring在类路径中是必要的,我看到了你的回答。谢谢你,伙计!我已经更新了我的答案,让它更清楚。我还打开了一个问题()来更新Spring引导文档的相关部分()TestConfiguration可用于定义额外的bean或测试定制,模拟只是许多用例中的一个。您可以简单地使用spring@MockBean来模拟Mockito…@MariuszS这个问题是关于Spock的。将Mockito与Spock结合使用会被认为是一种相当糟糕的代码味道。斯波克在里面有嘲弄的成分。在回答这个问题时,
@MockBean
不支持Spock mock。
dependencies {
// other dependencies
testCompile "org.codehaus.groovy:groovy-all:2.2.0"
testCompile "org.spockframework:spock-core:0.7-groovy-2.0"
}