Spring Boot 2.5 -> 2.6 に上げるときに Mockito のバージョンアップで困った話


本記事は NECソリューションイノベータ Advent Calendar 2021 の 12/20 の記事です。

こんにちは。

先日 Spring Boot を 2.5.3 から 2.6.1 にバージョンアップする機会があったのですが、単体テストが通らなくなって困った話をします。

テストが通らねぇ・・・

Spring Bootをバージョンアップして mvn clean test とすると・・・。

むむむ・・・。

java.lang.NoSuchMethodError: org.mockito.Answers.get()Lorg/mockito/stubbing/Answer;
    at org.powermock.api.extension.listener.AnnotationEnabler.standardInject(AnnotationEnabler.java:85)
    at org.powermock.api.extension.listener.AnnotationEnabler.beforeTestMethod(AnnotationEnabler.java:55)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)

これは謎・・・。

ぐーぐる先生に聞いてみよう

ぐーぐる先生に頼ります。
私は結構(いやかなり)横着なので、エラー内容をそのままコピペして検索しちゃいますw

ふむふむ・・・✧φ(ロ-ロ๑)

GitHub に Issue が上がってました。

Mockito のバージョンが上がったことで PowerMock との互換性がなくなったみたいですね。
バージョンダウンもワークアラウンドとしてあるようですが、これまで PowerMock に頼っていた静的メソッドのモッキングがMockitoでもできるようになったということで、せっかくなのでこれを試してみようと思います。

いざ実践

これを・・・

@RunWith(PowerMockRunner.class)
@PrepareForTest({ ClassA.class })
public class staticTest {

  @Test
  public void test() {
    PowerMockito.mockStatic(ClassA.class);
    when(ClassA.methodStatic()).thenReturn("OK!!");
    // 以下略
  }

}

こう書き換えます。

public class staticTest {

  @Test
  public void test() {
    try (MockStatic<ClassA> mocked = Mockito.mockStatic(ClassA.class)) {
      mocked.when(() -> ClassA.methodStatic()).thenReturn("OK!!");
      // 以下略
    }
  }
}

try で囲まずに最後にモックをクローズ(この例でいうと mocked.close() )する記法もあるのですが、 try で囲むとスコープが限定されてわかりやすいですし、クローズ漏れもなくなるのでこの記法を採用しました。

で、再テスト。

[INFO] Results:
[INFO]
[INFO] Tests run: 171, Failures: 0, Errors: 0, Skipped: 0
[INFO]
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 01:04 min
[INFO] Finished at: 2021-12-xxTHH:mm:ss+09:00
[INFO] ------------------------------------------------------------------------

テストをパスしました!

まとめ

Spring Bootってマイナー以上のバージョンを上げるとき、テストフレームワーク起因の非互換が発生することがちょいちょいあるんですよね。
これからもバージョンを上げるときは覚悟して挑みたいと思います(笑)

参考