統合テストを実行する最良の方法は何ですか(例: @IntegrationTest
)Spockで? bootstrap= 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'
}
...
何か不足していますか?
問題は、Spock SpringがSpringの@ContextConfiguration
アノテーションを探していて、それを見つけられないことです。厳密に言えばMyTestSpec
isは@ContextConfiguration
のメタ注釈であるため@SpringApplicationConfiguration
で注釈が付けられますが、Spock Springは検索の一部としてメタ注釈を考慮しません。この制限に対処するための issue があります。それまでの間、回避することができます。
@SpringApplicationConfiguration
が行うことは、ブート固有のコンテキストローダーを使用して@ContextConfiguration
をカスタマイズすることだけです。これは、適切に構成された@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.suayが言及したこと、彼らは@TestConfiguration
これは、統合テストでMockitoの代わりにSpringモックを使用する場合に便利です。
@TestConfiguration
新しいSpock DetachedMockFactory
を使用すると、Spock MocksをSpringコンテキストに注入するために必要なすべてのコンポーネントが得られます。
ここにサンプルコードを記載したブログ投稿があります: 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)
}
}
}
[〜#〜] update [〜#〜]Spockを注入するためにSpockでよりネイティブなサポートを得るために a PR があります統合テストのためにSpringコンテキストをモックします。新しい @SpringBean
および@SpringSpy
は@MockBean
および@SpyBean
注釈
[〜#〜] update [〜#〜]Spock 1.2にはこれらの変更が含まれるようになりました。ドキュメントが更新されるまで、ここに Spring統合テスト用Spock 1.2アノテーションのプレビュー があります。
新しい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/
ブートアプリケーションを起動してから、スポックテストを実行するセットアップを次に示します。
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
内のspockとgroovyに依存関係を追加することを忘れないでください
dependencies {
// other dependencies
testCompile "org.codehaus.groovy:groovy-all:2.2.0"
testCompile "org.spockframework:spock-core:0.7-groovy-2.0"
}