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

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

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

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

Java

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

Q&A

解決済

2回答

15803閲覧

JUnitでMockを使用してテスト対象のメソッド内で読んでいる別クラスのメソッドをMock化する方法について

H-T

総合スコア4

JUnit

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

Java

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

0グッド

0クリップ

投稿2021/10/16 19:52

JUnitとMockについて勉強しています。以下のことを実現したいです。

前提

JUnitを用いて以下のテストクラス:TestTargetService のユニットテストを行います。
このときに、テストクラスで呼び出しているMockTargetServiceクラスのgetAge()メソッドが未完成であるとして
Mock化を行いdoReturn().when()を使用して、getAgeの返却値を強制したいです。

テスト対象のソースコード

Java

1public class TestTargetService { 2 /** 3 * テスト対象のメソッド 4 */ 5 public boolean callService(String gender){ 6 String name = getName(gender); 7 System.out.println("Name:"+name); 8 9 MockTargetService mockServ = new MockTargetService(); 10 int age = mockServ.getAge(); // Mock化したい 11 12 System.out.println("Age:"+age); 13 if(age < 20){ 14 return true; 15 }else{ 16 return false; 17 } 18 } 19 20 private String getName(String gender){ 21 if(gender.equals("男")){ 22 return "Tarou"; 23 }else{ 24 return "Hanako"; 25 } 26 } 27}

Mock対象のソースコード

Java

1public class MockTargetService { 2 /** 3 * 未完成のメソッド 4 */ 5 public int getAge(){ 6 return 20; 7 } 8 9}

###目標・実現したいこと
getAge()の返却値は20ですがMockを用いて強制的に10にして、asserTrue();を成功させたいです。

###期待値

Name:Tarou Age:10 assertTrue成功

###試したこと
以下のテストクラス TestTargetServiceTestでテストを行っているのですがdoReturn()when()で強制した値に変わりません。

Java

1public class TestTargetServiceTest { 2 @InjectMocks 3 TestTargetService testServ = new TestTargetService(); 4 5 @Mock 6 MockTargetService mockServ; 7 @Before 8 public void setUp() { 9 MockitoAnnotations.initMocks(this); 10 } 11 12 @Test 13 public void モックありテスト(){ 14 String gender = "男"; 15 16 //getAge()の返却値を20⇒10に強制したい 17 doReturn(10).when(mockServ).getAge(); 18 boolean res = testServ.callService(gender); 19 assertTrue(res); 20 } 21}

###実際の出力内容・結果

Name:Tarou Age:20 assertTrue失敗

###その他
自分の認識としては
(1)@MockでMockを作成する。
(2)@InjectMocksで作成したMockを使用できるようにする。
(3)@Before内の処理でMockの初期化
(4)テスト対象のメソッド内でMock化したクラスのメソッドが呼ばれたらMock化した内容に切り替わる。
です。
(4)が上手くいかない原因は、Mock化したクラスのインスタンスとテスト対象のメソッド内で呼ばれているインスタンスが違うから切り替わらない?⇒その場合、そもそも実現したいことは行えないということでしょうか???

根本的に何か間違えているようでしたらそのことについてもご教授願いたいです。

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

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

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

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

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

guest

回答2

0

ベストアンサー

@InjectMocks で代入できるのは、フィールド変数のオブジェクトに対してのみになります。
今回だと、TestTargetService class は MockTargetService をメンバ変数としてではなくて、
実行メソッドの中でコンストラクタからインスタンスを生成しているので、Mockの注入ができていません。

対応方法としては以下のどちらかになると思います

  • MockTargetService を callService() 内で実行するのではなく、コンストラクタや DI の機能で代入する
  • Mockito 3.5 以降であれば、コンストラクタ する変数をモック化する方法を試す

投稿2021/10/16 20:05

編集2021/10/16 20:50
kiino

総合スコア539

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

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

H-T

2021/10/16 20:49

お早いご回答ありがとうございます。 大変参考になりました。
kiino

2021/10/16 20:52

B.A. の選択、ありがとうございます。 すいません、回答の内容が1点だけ間違っていました。 JUnit 3.5 以降であれば~と書いておりますが、正しくは Mockito 3.5 以降であれば。です。 Mockito 3.5 から メソッド内でコンストラクタを呼び出して作ったものをMock化する機能がこっそり追加されています。
H-T

2021/10/16 21:04

ありがとうございます。 修正したソースは最初の方法で試しました。2つ目の方も試してみたいと思います。
guest

0

ソースを以下のように追加・修正して解決しました。

Java

1public interface MockTargetIntf { 2 public int getAge(); 3}

Java

1// インターフェースを追加 2public class MockTargetService implements MockTargetIntf{ 3 /** 4 * 未完成のメソッド 5 */ 6 public int getAge(){ 7 return 20; 8 } 9}

Java

1 2public class TestTargetService { 3 /** 追加 */ 4 MockTargetIntf mockServ = null; 5 6 /** 追加 */ 7 public TestTargetService(){ 8 mockServ = new MockTargetService(); 9 } 10 11 /** 12 * テスト対象のメソッド 13 */ 14 public boolean callService(String gender){ 15 String name = getName(gender); 16 System.out.println("Name:"+name); 17 18 /** 修正 */ 19 int age = mockServ.getAge(); 20 System.out.println("Age:"+age); 21 if(age < 20){ 22 return true; 23 }else{ 24 return false; 25 } 26 } 27 28 private String getName(String gender){ 29 if(gender.equals("男")){ 30 return "Tarou"; 31 }else{ 32 return "Hanako"; 33 } 34 } 35}

投稿2021/10/16 20:59

H-T

総合スコア4

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問