使用Spring Boot和Spock进行集成测试

kuc*_*ram 36 java groovy gradle spock spring-boot

@IntegrationTest使用Spock 运行集成测试(例如)的最佳方法是什么?我想引导整个Spring Boot应用程序并执行一些HTTP调用来测试整个功能.

我可以使用JUnit(首先运行app然后执行测试):

@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
   }
}
Run Code Online (Sandbox Code Playgroud)

但是使用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
   }
}
Run Code Online (Sandbox Code Playgroud)

当然,对于Spock,我在Gradle构建文件中指定了正确的依赖项:

...
dependencies {
   testCompile 'org.spockframework:spock-core:0.7-groovy-2.0'
   testCompile 'org.spockframework:spock-spring:0.7-groovy-2.0'
}
...
Run Code Online (Sandbox Code Playgroud)

我错过了什么吗?

And*_*son 49

问题是Spock Spring正在寻找Spring的@ContextConfiguration注释而无法找到它.严格说来MyTestSpec 注释,@ContextConfiguration因为它是一个元注释,@SpringApplicationConfiguration但Spock Spring并不认为元注释是其搜索的一部分.解决此限制存在问题.在此期间,您可以解决它.

所有这@SpringApplicationConfiguration一切都是@ContextConfiguration使用特定于Boot的上下文加载器进行自定义.这意味着您可以通过使用适当配置的@ContextConfiguration注释来实现相同的效果:

@ContextConfiguration(loader = SpringApplicationContextLoader.class, classes = MyServer.class)
@WebAppConfiguration
@IntegrationTest
class MyTestSpec extends Specification {
    …
}
Run Code Online (Sandbox Code Playgroud)

更新:只是为了确保它是清楚的(并且基于注释,它不是),为此工作你需要org.spockframework:spock-spring在类路径上.

  • 不需要标记,并且您对MyServer的扣除是正确的.您可以在此处阅读有关@ContextConfiguration的更多信息:http://docs.spring.io/spring/docs/4.0.x/spring-framework-reference/htmlsingle/#integration-testing-annotations-spring.你有类似路径的spock-spring吗? (2认同)
  • 嗨@AndyWilkinson我刚刚回来让人们知道spock-spring在课堂上是必要的,我看到了你的反应.谢啦! (2认同)

Sne*_*kse 8

理想情况下,您将使用Spring Boot 1.4+和Spock 1.1+.

Spring Boot添加了许多有用的注释.除了@SpringBootTest@ ignacio.suay提到的,他们还添加了@TestConfiguration哪些内容,如果你想在集成测试中使用Spring模拟而不是Mockito.

如果你@TestConfiguration与新的Spock 结合使用DetachedMockFactory,那么你就拥有了将Spock Mocks注入Spring环境所需的所有组件.

我在这里有一个带有示例代码的博客文章:使用Spock Mocks进行Spring Integration Testing.

这很快又脏

@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)
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

更新一个PR可以在Spock中获得更多本机支持,以便将Spock Mocks注入到Spring环境中进行集成测试.新的@SpringBean@SpringSpy将是@MockBean@SpyBean注释

更新 Spock 1.2现在应该包含这些更改.在文档更新之前,这里是Spring集成测试的Spock 1.2注释预览.


小智 5

在新的 Spring Boot 版本(1.4)中,而不是使用:

@SpringApplicationConfiguration(classes = MyServer.class)
@WebAppConfiguration
@IntegrationTest
Run Code Online (Sandbox Code Playgroud)

你可以使用

@SpringBootTest(classes = MyServer.class)
Run Code Online (Sandbox Code Playgroud)

您将能够启动应用程序上下文并设置任何依赖项。

有关更多信息,请查看此示例: http://ignaciosuay.com/how-to-do-integration-tests-with-spring-boot-and-spock/