Posted at

@SpringBootTestがコンフィグレーションを自動検出する仕組み


バージョン


  • SprintBoot ... 2.1.9.RELEASE


仕組み

@SpringBootTest アノテーションはテスト実行時のコンフィグレーションクラスを自動検出する機能を備えています。SpringBootを使わない場合には @ContextConfiguration でコンフィグレーションを明示する必要があるわけですがそれが不要になるわけです。

自動検出されるのは @SpringBootConfiguration がついたクラスです。このアノテーションは @Configuration と同じ意味ですが @SpringBootTest によって自動的にテストコンフィグレーションに設定されるという点で挙動が異なります。

@SpringBootApplication アノテーションには @SpringBootConfiguration のアノテーションがついているので、 @SpringBootTest アノテーションは @SpringBootApplication のクラスをテストのコンフィグレーションとして設定するわけです。


コンフィグレーション

@SpringBootApplication

public class DemoApplication {

public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}

@Bean
public UserRepository userRepository() {
return new InMemoryUserRepository();
}

}



テスト

@RunWith(SpringRunner.class)

@SpringBootTest
public class DemoApplicationTests {

@Autowired
private UserRepository userRepository; // InMemoryUserRepositoryがインジェクションされる

}



自動検出からテスト用のコンフィグレーションクラスを除外

しかし、特定のテストのためにコンフィグレーションを作成する場合もあります。このコンフィグレーションクラスが自動検出されてしまうと意図していないコンフィグレーションが設定されてしまうことになります。


特定のテストのためのコンフィグレーション

@Configuration

public class SpecificTestConfiguration {

@Bean
public UserRepository hsqlUserRepository() {
return new HSQLUserRepository();
}

}



意図せずコンフィグレーションに設定される

@RunWith(SpringRunner.class)

@SpringBootTest
public class DemoApplicationTests {

@Autowired
private UserRepository hsqlUserRepository;

@Test
public void check() {
assertThat(hsqlUserRepository).isInstanceOf(HSQLUserRepository.class);
}

}


このような場合は @TestConfiguration を使用し自動検出の対象外としてコンフィグレーションクラスをマークしましす。コンフィグレーションを読み込みたい場合は @Import を使って読み込みます。


@TestConfigurationを使用

@TestConfiguration

public class SpecificTestConfiguration {

@Bean
public UserRepository hsqlUserRepository() {
return new HSQLUserRepository();
}

}



@Importを使用

@RunWith(SpringRunner.class)

@SpringBootTest
@Import(SpecificTestConfiguration.class)
public class DemoApplicationHsqlTests {

@Autowired
private UserRepository hsqlUserRepository;

@Test
public void check() {
assertThat(hsqlUserRepository).isInstanceOf(HSQLUserRepository.class);
}

}



参考