Help us understand the problem. What is going on with this article?

Junitでprivateメソッドのテスト方法

More than 1 year has passed since last update.

はじめに

Javaのテストユニットとして、Junitは当たり前に使用されるようになりました。
publicメソッドのテストは当然ですが、private,protectedメソッドの
テストはおろそかになりがちです。

ホワイトテストの実施は、プログラマーの義務を思いますので、
テストの実施が必要です。
そこで、すべてのメソッドのテスト実施を行う方法を紹介します。

テスト用のコードを用意

まず、テスト対象のコードを用意します。
以下は、参考までに。

Sample.java
public Sample {
    public int add(int x, int y) {
        return (x + y);
    }

    protected int minus(int x, int y) {
        return (x - y);
    }

    private int multiplication(int x, int y) {
        return (x * y);
    }
}

publicメソッドのテスト

SampleTest.java
import org.junit.Test;

public class SampleTest {
    @Test
    public void testEqual() {
        Sample sample = new Sample();
        int expected = 10;
        int actual = sample.add(8, 2);

        assertEquals(expected, actual);
    }
}

単純な足し算のテストです。
成功例のみですが、ごく普通なテストコードです。

protected,privateメソッドのテスト

インスタンスから、protected,privateメソッドできないため、
リフレクションと呼ばれる方法を使用してテストケースを作成します。

参考
Sample sample = new Sample();
Method method = Sample.class.getDeclaredMethod("<メソッド名>", 引数の型1, 引数の型2...);
method.setAccessible(true);
int actual = (戻り値の型)method.invoke(<インスタンス>,引数1,引数2...);

どのクラスにも存在するclass変数を使用して、getDeclaredMethod()メソッドで
メソッドを取得します。

取得したメソッドのsetAccessible(true)とします。
これは、外部からアクセスすることを許可するための設定です。
その後、method.invoke()メソッドでメソッドを実行します。

実際にテストケースを作成します。

SampleTest.java
import static org.junit.Assert.*;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

import org.junit.Test;

public class SampleTest {

    @Test
    public void testMinus()
        throws NoSuchMethodException,
        SecurityException,
        IllegalAccessException,
        IllegalArgumentException,
        InvocationTargetException
    {
        Sample sample = new Sample();
        int expected = 6;

        Method method = Sample.class.getDeclaredMethod("minus", int.class, int.class);
        method.setAccessible(true);

        int actual = (int)method.invoke(sample, 8, 2);

        assertEquals(expected, actual);
    }

    @Test
    public void testMultiplication()
        throws NoSuchMethodException,
        SecurityException,
        IllegalAccessException,
        IllegalArgumentException,
        InvocationTargetException
    {
        Sample sample = new Sample();
        int expected = 16;

        Method method = Sample.class.getDeclaredMethod("multiplication", int.class, int.class);
        method.setAccessible(true);

        int actual = (int)method.invoke(sample, 8, 2);

        assertEquals(expected, actual);
    }

おわりに

これで、作成したメソッドはすべてテストできるようになりました。

プログラマーにとって、バグは最大の敵です。
可能な限りバグを取り除く努力をしましょう。

village
気が付いたら、フリーランスのエンジニアになりました。 PHP + Laravel + Vue.js + Node.js = 今の仕事 python + 機械学習 = 勉強中
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away