質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.47%
JUnit

JUnitは、Javaで開発されたプログラムのユニットテストを行うためのアプリケーションフレームワークです。簡単にプログラムのユニットテストを自動化することができ、結果もわかりやすく表示されるため効率的に開発時間を短縮できます。

Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

Q&A

解決済

1回答

17219閲覧

JUnit5でメソッド内のnewのモックを作りたい

Youichi256

総合スコア204

JUnit

JUnitは、Javaで開発されたプログラムのユニットテストを行うためのアプリケーションフレームワークです。簡単にプログラムのユニットテストを自動化することができ、結果もわかりやすく表示されるため効率的に開発時間を短縮できます。

Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

0グッド

0クリップ

投稿2021/09/22 01:34

前提・実現したいこと

JUnit5で、メソッド内でnewしているクラスのモックを作りたいです。
開発段階なのでテスト対象のコードを変えることはできますが、getMain()メソッドで受け取った引数を使ってnewする必要があるため、メソッドから出せません。

発生している問題・エラーメッセージ

調べてみると、PowerMockito を使えば実現できそうというのはわかったのですが、うまくいかずに元のコードが動いています。

該当のソースコード

Java

1/* テスト対象 */ 2public class MainService { 3 public int getMain(int base, int add) { 4 SubService subService = new SubService(base); // コンストラクタも呼びたくない 5 return subService.getSub(add); 6 } 7}

Java

1/* モック対象 */ 2public class SubService { 3 private int base; 4 5 public SubService(int base) { 6 this.base = base; 7 } 8 9 public int getSub(int add) { 10 return this.base + add; 11 } 12}

Java

1/* テストコード */ 2import org.junit.jupiter.api.Assertions; 3import org.junit.jupiter.api.Test; 4import org.junit.jupiter.api.extension.ExtendWith; 5import org.mockito.InjectMocks; 6import org.mockito.Mock; 7import org.mockito.junit.jupiter.MockitoExtension; 8import org.powermock.api.mockito.PowerMockito; 9import org.powermock.core.classloader.annotations.PrepareForTest; 10 11@ExtendWith(MockitoExtension.class) 12@PrepareForTest({MainService.class, SubService.class}) 13class MainServiceTest { 14 @Mock 15 private SubService subService; 16 17 @InjectMocks 18 private MainService mainService; 19 20 @Test 21 public void testGetSum() throws Exception { 22 PowerMockito.when(subService.getSub(3)).thenReturn(6); 23 PowerMockito.when(subService.getSub(2)).thenReturn(5); 24 PowerMockito.whenNew(SubService.class).withAnyArguments().thenReturn(subService); 25 Assertions.assertEquals(6, subService.getSub(3)); // ここはパスする 26 Assertions.assertEquals(5, mainService.getMain(1, 2)); // ここは不一致(3になる) 27 } 28}

試したこと

メソッド内でnewしている場合には @PrepareForTest がいるような情報もあったので、付けてみました。

補足情報(FW/ツールのバージョンなど)

実行は、Eclipse(2021-06)から行っています。
テスト関係の追加ライブラリは、以下です(手動でjarを置いています)。

  • byte-buddy-1.9.9.jar
  • byte-buddy-agent-1.9.9.jar
  • mockito-core-3.12.4.jar
  • mockito-junit-jupiter-3.9.0.jar
  • objenesis-3.2.jar
  • powermock-api-mockito2-2.0.9.jar
  • powermock-api-support-2.0.9.jar
  • powermock-core-2.0.9.jar
  • powermock-module-javaagent-2.0.9.jar
  • powermock-reflect-2.0.9.jar

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

自己解決

PowerMockito は、Junit5に対応していないようでした。
最近のMokitoでは、それだけでメソッド内でnewしているクラスのモックにも対応できました。
Mockitoだけで行うテストコードは、以下のようにしました。

Java

1import static org.junit.jupiter.api.Assertions.*; 2import static org.mockito.Mockito.doReturn; 3import static org.mockito.Mockito.mockConstruction; 4 5import org.junit.jupiter.api.Test; 6import org.mockito.MockedConstruction; 7 8class MainServiceTest { 9 @Test 10 public void testGetSum() 11 throws NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException { 12 try (MockedConstruction<SubService> mock = mockConstruction(SubService.class, (subService, context) -> { 13 doReturn(5).when(subService).getSub(2); 14 })) { 15 16 MainService mainService = new MainService(); 17 assertEquals(5, mainService.getMain(1, 2)); 18 } 19 } 20}

テスト関係のライブラリは、以下を使用しています。

  • byte-buddy-1.11.16.jar
  • byte-buddy-agent-1.11.16.jar
  • mockito-core-3.12.4.jar
  • mockito-inline-3.12.4.jar

投稿2021/09/29 02:19

Youichi256

総合スコア204

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.47%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問