diff --git a/settings.gradle b/settings.gradle index 4a1f451239..b83d537b53 100644 --- a/settings.gradle +++ b/settings.gradle @@ -103,6 +103,7 @@ if (variant == 2.5) { } else { // require Java 17 which isn't supported by Groovy 2.5 include "spock-spring:boot3-test" + include "spock-spring:boot4-test" include "spock-spring:spring6-test" } diff --git a/spock-spring/boot4-test/boot4-test.gradle b/spock-spring/boot4-test/boot4-test.gradle new file mode 100644 index 0000000000..61c106eacf --- /dev/null +++ b/spock-spring/boot4-test/boot4-test.gradle @@ -0,0 +1,53 @@ +/* + * Copyright 2018 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +plugins { + id 'org.springframework.boot' version '4.0.3' + id 'io.spring.dependency-management' version '1.1.7' + id 'groovy' +} + +// Spring dependency management downgrades the jupiter version to 5.7.2 otherwise +ext['junit-jupiter.version'] = libs.versions.junit5.get() + +java { + toolchain { + languageVersion = JavaLanguageVersion.of(17) + } +} + +tasks.withType(JavaCompile).configureEach { + javaCompiler = javaToolchains.compilerFor { + languageVersion = JavaLanguageVersion.of(17) + } + options.encoding = 'UTF-8' +} + +dependencies { + implementation "org.springframework.boot:spring-boot-starter" + implementation "org.springframework.boot:spring-boot-starter-web" + implementation "org.springframework.boot:spring-boot-starter-data-jpa" + testImplementation "org.springframework.boot:spring-boot-starter-test" + testImplementation "org.springframework.boot:spring-boot-starter-data-jpa-test" + testImplementation "org.springframework.boot:spring-boot-starter-webmvc-test" + testImplementation projects.spockCore + testImplementation projects.spockSpring + + runtimeOnly "com.h2database:h2" +} + +tasks.named('test') { + useJUnitPlatform() +} diff --git a/spock-spring/boot4-test/src/main/java/org/spockframework/boot4/SimpleBootApp.java b/spock-spring/boot4-test/src/main/java/org/spockframework/boot4/SimpleBootApp.java new file mode 100644 index 0000000000..3f72e4f8d2 --- /dev/null +++ b/spock-spring/boot4-test/src/main/java/org/spockframework/boot4/SimpleBootApp.java @@ -0,0 +1,33 @@ +/* + * Copyright 2012-2013 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.spockframework.boot4; + +import org.springframework.boot.*; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class SimpleBootApp implements CommandLineRunner { + + @Override + public void run(String... args) { + System.out.println("Hello World"); + } + + public static void main(String[] args) throws Exception { + SpringApplication.run(SimpleBootApp.class, args); + } +} diff --git a/spock-spring/boot4-test/src/main/java/org/spockframework/boot4/jpa/Book.java b/spock-spring/boot4-test/src/main/java/org/spockframework/boot4/jpa/Book.java new file mode 100644 index 0000000000..83aafbdd57 --- /dev/null +++ b/spock-spring/boot4-test/src/main/java/org/spockframework/boot4/jpa/Book.java @@ -0,0 +1,40 @@ +/* + * Copyright 2012-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +package org.spockframework.boot4.jpa; + +import jakarta.persistence.*; + +/** + * JPA example entity class. + */ +@Entity +public class Book { + + @Id + @GeneratedValue + private Long id; + private String title; + + protected Book() { + // no-args JPA constructor + } + + public Book(String title) { + this.title = title; + } +} diff --git a/spock-spring/boot4-test/src/main/java/org/spockframework/boot4/jpa/BookRepository.java b/spock-spring/boot4-test/src/main/java/org/spockframework/boot4/jpa/BookRepository.java new file mode 100644 index 0000000000..286611239a --- /dev/null +++ b/spock-spring/boot4-test/src/main/java/org/spockframework/boot4/jpa/BookRepository.java @@ -0,0 +1,26 @@ +/* + * Copyright 2012-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +package org.spockframework.boot4.jpa; + +import org.springframework.data.repository.CrudRepository; + +/** + * Spring-Data repository for {@link Book} entities. + */ +public interface BookRepository extends CrudRepository { +} diff --git a/spock-spring/boot4-test/src/main/java/org/spockframework/boot4/service/HelloWorldService.java b/spock-spring/boot4-test/src/main/java/org/spockframework/boot4/service/HelloWorldService.java new file mode 100644 index 0000000000..e1281220e5 --- /dev/null +++ b/spock-spring/boot4-test/src/main/java/org/spockframework/boot4/service/HelloWorldService.java @@ -0,0 +1,32 @@ +/* + * Copyright 2012-2013 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.spockframework.boot4.service; + +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Component; + +@Component +public class HelloWorldService { + + @Value("${name:World}") + private String name; + + public String getHelloMessage() { + return "Hello " + this.name; + } + +} diff --git a/spock-spring/boot4-test/src/main/java/org/spockframework/boot4/service/ScopedHelloWorldService.java b/spock-spring/boot4-test/src/main/java/org/spockframework/boot4/service/ScopedHelloWorldService.java new file mode 100644 index 0000000000..9d31445450 --- /dev/null +++ b/spock-spring/boot4-test/src/main/java/org/spockframework/boot4/service/ScopedHelloWorldService.java @@ -0,0 +1,19 @@ +package org.spockframework.boot4.service; + +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.ScopedProxyMode; +import org.springframework.stereotype.Component; +import org.springframework.web.context.annotation.RequestScope; + +@RequestScope(proxyMode = ScopedProxyMode.TARGET_CLASS) +@Component +public class ScopedHelloWorldService { + + @Value("${name:World Scope!}") + private String name; + + public String getHelloMessage() { + return "Hello " + this.name; + } + +} diff --git a/spock-spring/boot4-test/src/main/java/org/spockframework/boot4/web/HelloWorldController.java b/spock-spring/boot4-test/src/main/java/org/spockframework/boot4/web/HelloWorldController.java new file mode 100644 index 0000000000..869a545ae9 --- /dev/null +++ b/spock-spring/boot4-test/src/main/java/org/spockframework/boot4/web/HelloWorldController.java @@ -0,0 +1,26 @@ +package org.spockframework.boot4.web; + +import org.spockframework.boot4.service.HelloWorldService; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.*; + +/** + * Spring-MVC controller class. + */ +@RestController +public class HelloWorldController { + + private HelloWorldService service; + + @Autowired + public HelloWorldController(HelloWorldService service) { + this.service = service; + } + + @RequestMapping("/") + public String hello() { + return service.getHelloMessage(); + } + +} diff --git a/spock-spring/boot4-test/src/main/resources/application.properties b/spock-spring/boot4-test/src/main/resources/application.properties new file mode 100644 index 0000000000..29f32f228b --- /dev/null +++ b/spock-spring/boot4-test/src/main/resources/application.properties @@ -0,0 +1,3 @@ +name=Spock +logging.level.root=OFF +spring.jpa.hibernate.ddl-auto=create diff --git a/spock-spring/boot4-test/src/test/groovy/org/spockframework/boot4/DataJpaTestIntegrationSpec.groovy b/spock-spring/boot4-test/src/test/groovy/org/spockframework/boot4/DataJpaTestIntegrationSpec.groovy new file mode 100644 index 0000000000..cbc677c299 --- /dev/null +++ b/spock-spring/boot4-test/src/test/groovy/org/spockframework/boot4/DataJpaTestIntegrationSpec.groovy @@ -0,0 +1,49 @@ +/* + * Copyright 2012-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +package org.spockframework.boot4 + +import org.spockframework.boot4.jpa.* +import spock.lang.Specification + +import org.springframework.beans.factory.annotation.Autowired +import org.springframework.boot.data.jpa.test.autoconfigure.DataJpaTest +import org.springframework.boot.jpa.test.autoconfigure.TestEntityManager + +/** + * Integration tests for ensuring compatibility with Spring-Boot's {@link DataJpaTest} annotation. + */ +@DataJpaTest +class DataJpaTestIntegrationSpec extends Specification { + + @Autowired + TestEntityManager entityManager + + @Autowired + BookRepository bookRepository + + def "spring context loads for data jpa slice"() { + given: "some existing books" + entityManager.persist(new Book("Moby Dick")) + entityManager.persist(new Book("Testing Spring with Spock")) + + expect: "the correct count is inside the repository" + bookRepository.count() == 2L + } + + +} diff --git a/spock-spring/boot4-test/src/test/groovy/org/spockframework/boot4/SimpleBootAppIntegrationSpec.groovy b/spock-spring/boot4-test/src/test/groovy/org/spockframework/boot4/SimpleBootAppIntegrationSpec.groovy new file mode 100644 index 0000000000..c12c474cd7 --- /dev/null +++ b/spock-spring/boot4-test/src/test/groovy/org/spockframework/boot4/SimpleBootAppIntegrationSpec.groovy @@ -0,0 +1,45 @@ +/* + * Copyright 2012-2014 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.spockframework.boot4 + +import spock.lang.Specification + +import org.springframework.beans.factory.annotation.Autowired +import org.springframework.boot.test.context.SpringBootTest +import org.springframework.context.ApplicationContext + +/** + * Spock test for {@link org.spockframework.boot4.SimpleBootApp}. + * Adapted from https://github.com/spring-projects/spring-boot/blob/master/spring-boot-samples/ + * spring-boot2-sample-simple/src/test/java/sample/simple/SpringTestSampleSimpleApplicationTests.java. + * + * @author Dave Syer + * @author Peter Niederwieser + */ +@SpringBootTest(classes = SimpleBootApp) +class SimpleBootAppIntegrationSpec extends Specification { + @Autowired + ApplicationContext context + + def "test context loads"() { + expect: + context != null + context.containsBean("helloWorldService") + context.containsBean("simpleBootApp") + context.containsBean("scopedHelloWorldService") + } +} diff --git a/spock-spring/boot4-test/src/test/groovy/org/spockframework/boot4/SpringBeanIntegrationSpec.groovy b/spock-spring/boot4-test/src/test/groovy/org/spockframework/boot4/SpringBeanIntegrationSpec.groovy new file mode 100644 index 0000000000..b299180654 --- /dev/null +++ b/spock-spring/boot4-test/src/test/groovy/org/spockframework/boot4/SpringBeanIntegrationSpec.groovy @@ -0,0 +1,55 @@ +/* + * Copyright 2012-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.spockframework.boot4 + +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status + +import org.spockframework.boot4.service.HelloWorldService +import org.spockframework.spring.SpringBean +import spock.lang.Specification + +import org.springframework.beans.factory.annotation.Autowired +import org.springframework.boot.webmvc.test.autoconfigure.WebMvcTest +import org.springframework.test.web.servlet.MockMvc +import org.springframework.test.web.servlet.request.MockMvcRequestBuilders + +/** + * Integration tests for ensuring compatibility with Spring-Boot's {@link WebMvcTest} annotation + * in conjunction with {@link SpringBean}. + */ +//tag::include[] +@WebMvcTest +class SpringBeanIntegrationSpec extends Specification { + + @Autowired + MockMvc mvc + + @SpringBean + HelloWorldService helloWorldService = Stub() + + def "spring context loads for web mvc slice"() { + given: + helloWorldService.getHelloMessage() >> 'hello world' + + expect: "controller is available" + mvc.perform(MockMvcRequestBuilders.get("/")) + .andExpect(status().isOk()) + .andExpect(content().string("hello world")) + } +} +//end::include[] diff --git a/spock-spring/boot4-test/src/test/groovy/org/spockframework/boot4/SpringBootTestAnnotationIntegrationSpec.groovy b/spock-spring/boot4-test/src/test/groovy/org/spockframework/boot4/SpringBootTestAnnotationIntegrationSpec.groovy new file mode 100644 index 0000000000..ad376c0c59 --- /dev/null +++ b/spock-spring/boot4-test/src/test/groovy/org/spockframework/boot4/SpringBootTestAnnotationIntegrationSpec.groovy @@ -0,0 +1,44 @@ +/* + * Copyright 2012-2014 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.spockframework.boot4 + +import spock.lang.Specification + +import org.springframework.beans.factory.annotation.Autowired +import org.springframework.boot.test.context.SpringBootTest +import org.springframework.context.ApplicationContext + +/** + * Integration test similar to {@link SimpleBootAppIntegrationSpec} but using the {@link SpringBootTest} annotation. + * + * SpringBootTest.webEnvironment needs to something other than {@link SpringBootTest.WebEnvironment.MOCK}, + * otherwise there is always a MockRequest active. + */ +@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.NONE, + properties = ['spring.main.allow-bean-definition-overriding=true']) +class SpringBootTestAnnotationIntegrationSpec extends Specification { + @Autowired + ApplicationContext context + + def "test context loads"() { + expect: + context != null + context.containsBean("helloWorldService") + context.containsBean("simpleBootApp") + context.containsBean("scopedHelloWorldService") + } +} diff --git a/spock-spring/boot4-test/src/test/groovy/org/spockframework/boot4/SpringBootTestAnnotationScopedMockSpec.groovy b/spock-spring/boot4-test/src/test/groovy/org/spockframework/boot4/SpringBootTestAnnotationScopedMockSpec.groovy new file mode 100644 index 0000000000..04aec11c0e --- /dev/null +++ b/spock-spring/boot4-test/src/test/groovy/org/spockframework/boot4/SpringBootTestAnnotationScopedMockSpec.groovy @@ -0,0 +1,71 @@ +/* + * Copyright 2012-2014 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.spockframework.boot4 + +import org.spockframework.boot4.service.HelloWorldService +import org.spockframework.spring.ScanScopedBeans +import spock.lang.Specification +import spock.mock.DetachedMockFactory + +import org.springframework.beans.factory.annotation.Autowired +import org.springframework.boot.test.context.* +import org.springframework.context.ApplicationContext +import org.springframework.context.annotation.Bean + +/** + * Tests enabled scanning of scoped beans. + */ +@ScanScopedBeans +@SpringBootTest(properties = ['spring.main.allow-bean-definition-overriding=true']) +class SpringBootTestAnnotationScopedMockSpec extends Specification { + @Autowired + ApplicationContext context + + @Autowired + HelloWorldService helloWorldService + + def "test context loads"() { + expect: + context != null + context.containsBean("helloWorldService") + !context.containsBean("scopedTarget.helloWorldService") + context.containsBean("simpleBootApp") + } + + def "scoped mock can be used"() { + expect: + !helloWorldService.class.simpleName.startsWith('HelloWorldService$$EnhancerBySpringCGLIB$$') + + when: + def result = helloWorldService.helloMessage + + then: + 1 * helloWorldService.getHelloMessage() >> 'sup?' + result == 'sup?' + } + + + @TestConfiguration + static class MockConfig { + def detachedMockFactory = new DetachedMockFactory() + + @Bean + HelloWorldService helloWorldService() { + return detachedMockFactory.Mock(HelloWorldService) + } + } +} diff --git a/spock-spring/boot4-test/src/test/groovy/org/spockframework/boot4/SpringBootTestAnnotationScopedProxyMockSpec.groovy b/spock-spring/boot4-test/src/test/groovy/org/spockframework/boot4/SpringBootTestAnnotationScopedProxyMockSpec.groovy new file mode 100644 index 0000000000..08bf285c76 --- /dev/null +++ b/spock-spring/boot4-test/src/test/groovy/org/spockframework/boot4/SpringBootTestAnnotationScopedProxyMockSpec.groovy @@ -0,0 +1,76 @@ +/* + * Copyright 2012-2014 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.spockframework.boot4 + +import org.spockframework.boot4.service.HelloWorldService +import org.spockframework.spring.ScanScopedBeans +import spock.lang.Specification +import spock.mock.DetachedMockFactory + +import org.springframework.beans.factory.annotation.Autowired +import org.springframework.boot.test.context.* +import org.springframework.context.ApplicationContext +import org.springframework.context.annotation.* +import org.springframework.web.context.annotation.RequestScope + +/** + * Tests enabled scanning of scoped and proxied beans. + */ +@ScanScopedBeans +@SpringBootTest(properties = ['spring.main.allow-bean-definition-overriding=true']) +class SpringBootTestAnnotationScopedProxyMockSpec extends Specification { + @Autowired + ApplicationContext context + + @Autowired + HelloWorldService helloWorldService + + def "test context loads"() { + expect: + context != null + context.containsBean("helloWorldService") + context.containsBean("scopedTarget.helloWorldService") + context.containsBean("simpleBootApp") + } + + def "scoped mock can be used"() { + given: + def helloWorldServiceMock = context.getBean("scopedTarget.helloWorldService") as HelloWorldService + + expect: + helloWorldService.class.simpleName.startsWith('HelloWorldService$$SpringCGLIB$$') + + when: + def result = helloWorldService.helloMessage + + then: + 1 * helloWorldServiceMock.getHelloMessage() >> 'sup?' + result == 'sup?' + } + + + @TestConfiguration + static class MockConfig { + def detachedMockFactory = new DetachedMockFactory() + + @Bean + @RequestScope(proxyMode = ScopedProxyMode.TARGET_CLASS) + HelloWorldService helloWorldService() { + return detachedMockFactory.Mock(HelloWorldService) + } + } +} diff --git a/spock-spring/boot4-test/src/test/groovy/org/spockframework/boot4/WebMvcTestIntegrationSpec.groovy b/spock-spring/boot4-test/src/test/groovy/org/spockframework/boot4/WebMvcTestIntegrationSpec.groovy new file mode 100644 index 0000000000..39afff8c50 --- /dev/null +++ b/spock-spring/boot4-test/src/test/groovy/org/spockframework/boot4/WebMvcTestIntegrationSpec.groovy @@ -0,0 +1,66 @@ +/* + * Copyright 2012-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.spockframework.boot4 + +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status + +import org.spockframework.boot4.service.HelloWorldService +import spock.lang.Specification +import spock.mock.DetachedMockFactory + +import org.springframework.beans.factory.annotation.Autowired +import org.springframework.boot.webmvc.test.autoconfigure.WebMvcTest +import org.springframework.boot.test.context.TestConfiguration +import org.springframework.context.annotation.Bean +import org.springframework.test.web.servlet.MockMvc +import org.springframework.test.web.servlet.request.MockMvcRequestBuilders + +/** + * Integration tests for ensuring compatibility with Spring-Boot's {@link WebMvcTest} annotation. + */ +//tag::include[] +@WebMvcTest +class WebMvcTestIntegrationSpec extends Specification { + + @Autowired + MockMvc mvc + + @Autowired + HelloWorldService helloWorldService + + def "spring context loads for web mvc slice"() { + given: + helloWorldService.getHelloMessage() >> 'hello world' + + expect: "controller is available" + mvc.perform(MockMvcRequestBuilders.get("/")) + .andExpect(status().isOk()) + .andExpect(content().string("hello world")) + } + + @TestConfiguration + static class MockConfig { + def detachedMockFactory = new DetachedMockFactory() + + @Bean + HelloWorldService helloWorldService() { + return detachedMockFactory.Stub(HelloWorldService) + } + } +} +//end::include[]