Java

Javaで無理やりシングルトンをモックにする方法

投稿日:2017年3月26日 更新日:

ソフトウェアテスト
シングルトンのオブジェクトを使っているクラスをテストしたいときどうするか?
今回はMockitoを使って実現する。
ちなみに、最初からDIを使っていればこんなことはしなくてもいい。

Mockito

Javaのモックフレームワークの一つ。
公式サイトから入手できる。

モック化の対象

こんな感じのシングルトンクラス。

public class Manager {
 
    //インスタンス
    private static Manager inst = null;
 
    //シングルトンインスタンス取得
    public static synchronized Manager getInstance() {
        if (inst == null) {
            inst = new Manager();
        }
        return inst;
    }
 
    //デフォルトコンストラクタ(シングルトンパターンのためprivateで宣言)
    private Manager() { }
 
    //何か処理
    public void doSomething(String param) {
    }
}

テスト対象

シングルトンオブジェクトをこんな感じで呼び出している。

public class User {
    public void call() {
        Manager.getInstance().doSomething("パラメーター");
    }
}

テスト

リフレクションも使って無理やりインスタンスを置き換える。

public class UserTest extends TestCase {
 
    public void test_callメソッド() throws Exception {
        //mockitでManagerのモックを作る
        Manager mockManager = mock(Manager.class);
 
        //リフレクションでインスタンスをモックに書き換えてしまう
        Field manager = Manager.class.getDeclaredField("inst");
        if (!manager.isAccessible()) {
            manager.setAccessible(true);
        }
        manager.set(Manager.getInstance(), mockManager);
 
        //モックの動きを指定
        doAnswer(new Answer<Object>() {
            @Override
            public Object answer(InvocationOnMock invocation) throws Throwable {
 
                //呼ばれた時の引数も取り出せる
                Object[] args = invocation.getArguments();
                assertEquals("引数の確認", "パラメーター", args[0]);
                return null;
            }
        }).when(mockManager).doSomething(anyString());
 
        //実際に実行
        new User().call();
    }
}

この例ではシングルトンオブジェクトのメソッドを呼んでいることを確認しているが、
メソッドの挙動を指定して別の試験を行うこともできる。

酔いどれまさになう。

-Java
-, , ,

執筆者:


comment

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください

関連記事

テスト中のプログラマ

JavaのモックライブラリJMockitの初歩的な使い方

テスト中のプログラマ 実装や単体試験中にはモックが欲しくなるもの。 Javaのモックライブラリは複数あるが、JMockitの使い方について。 ここに書いたこと以外にも色々できる強力なライブラリだ。 入 …

カテゴリー