0
2

More than 3 years have passed since last update.

Spring boot + JUnit5で@SpringBootTestアノテーションを使わずにApplicationContextを使う

Last updated at Posted at 2020-09-14

この記事の対象

Spring 2.2.x
spring-test 5.2
JUnit 5.6

なにがしたかったの?

テスト実行をする際に、@SpringBootApplicationによるrunが実行されてしまうことを回避したかったのですが、そうすると、テストコード側でApplicationContextを利用できなくてハマってしまいました。
解決できたので、備忘録として…

なにゆえにハマったのか?

下記のようなテストコードを書いていました。

@SpringJUnitConfig(classes = {ComponentA.class})
@EnableConfigurationProperties(value = {PrimaryConfiguration.class, SecondaryConfiguration.class})
@ExtendWith(SpringExtension.class)
public class ComponentATest {
    @Autowired
    public ApplicationContext ctx;

    @Test
    public final void testA {
        ComponentA testObj = new ComponentA();
        ctx.getAutowireCapableBeanFactory().autowireBean(testObj);
        // テスト対象メソッドの実行
        testObj.exec()
    }

上記のテストのようにテスト対象のクラス内にAutowiredしているオブジェクトが存在するため、AutowireCapableBeanFactoryを利用して、インスタンスにDIを注入しようとしたのですが、ApplicationContextがDIされず、nullが返却されるため、テストが出来ないという状態でした。

先の通り、@SpringJUnitConfigを利用せずに、@SpringBootTestを利用すれば良いのですが、諸事情により、本体アプリが実行されてしまうと不都合があるため、@SpringBootTestを使用せずにテストを実行したかったのです。

解決方法

@SpringJUnitConfigアノテーションにinitializersを付与するだけでOKです。

@SpringJUnitConfig(classes = {ComponentA.class},
    initializers = ConfigFileApplicationContextInitializer.class)

ただし、initializersによりテストメソッド実行の度にApplicationContextを再生成するので、テストケースが大量にある場合は、素直にDIオブジェクトをMock/Spyした方が良いと思います。

これだけのために半日を無駄にした私のような犠牲者を出さないために…お役たてば幸いです。

0
2
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
2