1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

JUnitでprivateメソッドのテストカバレッジを充足させたい場合

Last updated at Posted at 2019-08-08

こんな時に

どうしてもJUnitでprivateメソッドも含めてカバレッジ100%にしたい!
(基本はpublicメソッドのテスト経由で全部通した方が自然)

例えば

以下のようなクラスで一箇所だけ自然にテストを通せないprivateメソッドがあったとする。
(中身がスカスカなのはご愛嬌)

SampleUtil.java

private String getStatus(String param, TestEntity testEntity) {
  String result = null;
  switch (param) {
    case "1":
      result = "A" + testEntity.getCode();
      break;
    case "2":
      result = "B" + testEntity.getCode();
      break;
    case "3":
      result = "C" + testEntity.getCode();
      break;
    default :
      result = "Z" + testEntity.getCode(); // ← ここのカバレッジが通らない!
  }
  return result;
}

対応方法

Mockitoを使う
https://site.mockito.org/

準備

私の場合はSpringBootとJUnitは既に導入済みのため、
dependencyに以下を追記してMockitoのライブラリを取得する。

Maven利用の場合

pom.xml
<!-- https://mvnrepository.com/artifact/org.mockito/mockito-all -->
<dependency>
    <groupId>org.mockito</groupId>
    <artifactId>mockito-all</artifactId>
    <version>1.10.19</version>
    <scope>test</scope>
</dependency>

Gradle利用なら

build.gradle
dependencies {
  // https://mvnrepository.com/artifact/org.mockito/mockito-all
  testCompile group: 'org.mockito', name: 'mockito-all', version: '1.10.19'
}

使い方

テストクラスで以下の様に書けばいい

SampleUtilTest.java

  private SampleUtil sampleUtil;

  private static int testId = 1; // 後の検証で使う変数

  @Test
  public void getStatus() {

    // SampleUtil#getStatusを実行できる様に設定
    Method method = SampleUtil.class.getDeclaredMethod("getStatus", String.class, TestEntity.class);
    method.setAccessible(true);

    // テスト用のパラメータ設定
    String param = "4"; 
    TestEntity testEntity = new TestEntity();
    testEntity.setCode("001");

    // テスト実行
    String status = (String) method.invoke(sampleUtil, param, testEntity);
    assertThat(status, is("Z001"));
  }

SampleUtilのgetStatus()メソッドに対してaccessible=trueを設定することでアクセッサレベルを無視して呼び出すことが可能になる。

応用編

テスト内でprivate変数に対してgetやsetしたい場合

以下のtestIdはSampleUtil.java内でprivate定義されている変数。
ここではgetしてみる。

SampleUtilTest.java

  @Test
  public void getParams() {
    SampleUtil sampleUtil = new SampleUtil();
    assertThat(Whitebox.getInternalState(sampleUtil, "testId"), is(1));
  }

この様に実装することでアクセッサレベルを無視して呼び出すことが可能。

最後に

ここで紹介した以外にもstaticメソッドを書き換えたりJUnitのテストの幅が広がる様な機能を多く備えているので、
興味のある人は突っ込んで調べてみるといいかも。

1
1
0

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
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?