Integration Test with Spring Boot and Spock

China☆狼群 提交于 2019-11-27 11:13:31

The problem is that Spock Spring is looking for Spring's @ContextConfiguration annotation and doesn't manage to find it. Strictly speaking MyTestSpec is annotated with @ContextConfiguration as it's a meta-annotation on @SpringApplicationConfiguration but Spock Spring doesn't consider meta-annotations as part of its search. There's an issue to address this limitation. In the meantime you can work around it.

All that @SpringApplicationConfiguration is doing is customising @ContextConfiguration with a Boot-specific context loader. This means that you can achieve the same effect by using an appropriately configured @ContextConfiguration annotation instead:

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

Update: Just to make sure it's clear (and based on the comments, it wasn't), for this to work you need to have org.spockframework:spock-spring on the classpath.

Ideally you'll use Spring Boot 1.4+ and Spock 1.1+.

Spring Boot added a lot of useful annotations. In addition to that @SpringBootTest that @ignacio.suay mentioned, they also added @TestConfiguration which is useful if you want to use Spring mocks in your integration tests instead of Mockito.

If you combine @TestConfiguration with the new Spock DetachedMockFactory, then you have all of the components you'll need to inject Spock Mocks into your Spring context.

I have a blog post with sample code here: Spring Integration Testing with Spock Mocks.

The quick and dirty is this

@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)
    }
  }
}

UPDATE There is a PR to get more native support in Spock for injecting Spock Mocks into the Spring context for integration testing. The new @SpringBean and @SpringSpy would be like the @MockBean and @SpyBean annotations

UPDATE Spock 1.2 should now include these changes. Until the documentation is updated, here is a preview of the Spock 1.2 Annotations for Spring Integration Testing .

In the new Spring Boot version (1.4) instead of using:

@SpringApplicationConfiguration(classes = MyServer.class)
@WebAppConfiguration
@IntegrationTest

You could use

@SpringBootTest(classes = MyServer.class)

and you will be able to start the application context and set any dependency.

for further information, please have a look to this example: http://ignaciosuay.com/how-to-do-integration-tests-with-spring-boot-and-spock/

Here is a setup which starts up boot applicaiton and then runs spock tests:

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'
}
}

And remember to add dependencies to spock and groovy inside build.gradle

dependencies {
    // other dependencies
    testCompile "org.codehaus.groovy:groovy-all:2.2.0"
    testCompile "org.spockframework:spock-core:0.7-groovy-2.0"
}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!