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

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

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

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

Java

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

Spring Boot

Spring Bootは、Javaのフレームワークの一つ。Springプロジェクトが提供する様々なフレームワークを統合した、アプリケーションを高速で開発するために設計されたフレームワークです。

Q&A

解決済

1回答

3074閲覧

Mockitoを使用したprivateメソッドのテストを実施したい

gu3.net

総合スコア11

JUnit

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

Java

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

Spring Boot

Spring Bootは、Javaのフレームワークの一つ。Springプロジェクトが提供する様々なフレームワークを統合した、アプリケーションを高速で開発するために設計されたフレームワークです。

0グッド

1クリップ

投稿2017/10/02 12:56

編集2017/10/02 13:14

###前提・実現したいこと
Mockitoを使用して、privateメソッドの単体テストを作成しています。
privateメソッド内でインスタンスをnewして、メソッド呼び出しをしている箇所をMock化し、
自分で生成したオブジェクトをそのまま返すようなテストを実行したいと考えています。

下記のように実装しましたが、NullPointerになっています。
CommandクラスをMock化しているので、sampleA内のCmd.executeは実行されず、
when句で設定したResultが返却されると思っているのですが、どうやら実行されており、Processbuilder.startでエラーとなっています。

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

Caused by: java.lang.NullPointerException at java.lang.ProcessBuilder.start(ProcessBuilder.java:1012)

###該当のソースコード

java

1@RunWith(SpringRunner.class) 2@SpringBootTest 3public class SampleATest { 4 5 private static final SampleA sampleA = new SampleA(); 6 7 @Test 8 public void testExecuteCommand() throws Exception { 9 Method method = SampleA.class.getDeclaredMethod("executeCommand", Object.class, String.class); 10 method.setAccessible(true); 11 12 Result result = mock(Result.class); 13 Whitebox.setInternalState(result, "exitValue", 0); 14 15 Command command = spy(Command.class); 16 when(command.execute(anyObject(), anyObject())).thenReturn(result); 17 18 Result result2 = (Result) method.invoke(sampleA, obj, strs); 19 assertThat(result2.getExitValue(), is(0)); 20 } 21}

java

1public class SampleA { 2 private void executeCommand(Object Obj, String str) { 3 Command Cmd = new Command(); 4 Result result = Cmd.execute(obj, str); 5 if (result.getExitValue() != 0) { 6 throw new Exception("error" + result.getExitValue()); 7 } 8 } 9}

Java

1public class Command { 2 public Result execute(Object Obj, String param) { 3 Result result = new Result(); 4 5 List<String> CmdList = new ArrayList<>(); 6 CmdList.add(obj.command); 7 CmdList.add(param); 8 9 ProcessBuilder builder = new ProcessBuilder(CmdList); 10 Process process = builder.start(); 11 try { 12 result.exitValue = process.exitValue(); 13 } finally { 14 process.destroy(); 15 } 16 17 return result; 18 } 19}

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

  • SpringBoot 1.5.x
  • JUnit 4.x
  • Mockito 2.x

コードにマスクをしておりますので、不整合がありましたら申し訳ありません。

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

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

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

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

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

guest

回答1

0

ベストアンサー

気になる点がいくつかあります。

  • assertしている内容
    Result result2 = (Result) method.invoke(sampleA, obj, strs); のところ、メソッドに返り値があるように書かれていますが、ここで呼ばれる「executeCommand」メソッドはvoidです。
    SampleA内でresultがどこにも保存されないため、この場合、Exceptionがなく終了すること、くらいしか確認できないかもしれません(省略しただけならすみません)。

  • CommandクラスがSampleAのメソッド内でnewされている。
    一般に、メソッド内でnewしてオブジェクトを作るようなソースは、依存が生まれテストがしづらいとされています。⇒参考
    こうしてしまうとモック化は少し複雑化します。おそらくMockitoだけでは出来なさそうです。
    以下のようにしてなんとかなりました。

    pom.xml

<dependency> <groupId>org.powermock</groupId> <artifactId>powermock-module-junit4</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>org.powermock</groupId> <artifactId>powermock-api-mockito2</artifactId> <scope>test</scope> </dependency> ```

テストケース

java

1@RunWith(PowerMockRunner.class) 2// @SpringBootTest 3public class SampleATest { 4 5 // private static final SampleA sampleA = new SampleA(); <- モック化が必要 6 7 @Test 8 public void testExecuteCommand() throws Exception { 9 SampleA sampleA = mock(SampleA.class); 10// ~中略~ 11 Result result = new Result(); 12 result.setExitValue(0); // <- ここは想像です 13 when(command.execute(any(Object.class), anyString())).thenReturn(result); 14 whenNew(Command.class).withNoArguments().thenReturn(command); // ※1

※1 -> これをするのにPowerMockが必要です。Commandクラスをnewしたときにcommand変数を返す としています。

1.assertしたい内容、2.実装内での依存(new)の排除、2つの観点でソースを見てみてください。
ご不明点ありましたら、追記をお願いします。

投稿2017/10/06 07:02

maruhachi

総合スコア26

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.49%

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

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

質問する

関連した質問