Powermock series 2-プライベートメソッドのテスト、プライベート構造関数

2696 ワード

Getting Started


use : rely on EasyMock or Mockito and a test framework

Bypass Encapsulation mockパッケージを迂回


翻訳https://github.com/powermock/powermock/wiki/Bypass-Encapsulation

Quick summary


Whitebox
class provides a set of methods which could you help bypass encapsulation if it required. Usually, it's not a good idea to get/modify non-public fields, but sometimes it's only way to cover code by test for future refactoring.
  • Use Whitebox.setInternalState(..) to set a non-public member of an instance or class. 内部プライベートメンバーの設定
  • Use Whitebox.getInternalState(..) to get a non-public member of an instance or class. 社内プライベートメンバーの取得
  • Use Whitebox.invokeMethod(..) to invoke a non-public method of an instance or class. プライベートメソッド
  • を呼び出す
  • Use Whitebox.invokeConstructor(..) to create an instance of a class with a private constructor. プライベートコンストラクタ
  • を呼び出す

    例を挙げる

  • 1プライベートメソッド
  • を呼び出す.
    private int sum(int a, int b) {
        return a+b;
    }
    
    int sum = Whitebox. invokeMethod(myInstance, "sum", 1, 2);
    
  • 2プライベートメソッドリロード状況
  • ...
    private int myMethod(int id) {      
        return 2*id;
    }
    
    private int myMethod(Integer id) {      
            return 3*id;
    }
    ...
    

    入力パラメータclassに基づいてどれを使用するかを判断する
    int result = Whitebox. invokeMethod(myInstance, new Class>[]{int.class}, "myMethod", 1);
    
  • 3プライベートコンストラクタ
  • を呼び出す
    public class PrivateConstructorInstantiationDemo {
    
        private final int state;
    
        private PrivateConstructorInstantiationDemo(int state) {
            this.state = state;
        }
    
        public int getState() {
            return state;
        }
    }
    

    呼び出し:
    PrivateConstructorInstantiationDemo instance =  WhiteBox.invokeConstructor(
                    PrivateConstructorInstantiationDemo.class, 43);
    
  • コンストラクタリロードの場合
  • public class PrivateConstructorInstantiationDemo {
    
        private final int state;
    
        private PrivateConstructorInstantiationDemo(int state) {
            this.state = state;
        }
    
        private PrivateConstructorInstantiationDemo(Integer state) {
                  this.state = state;
                  // do something else
        }
    
        public int getState() {
            return state;
        }
    }
    

    呼び出し:
    PrivateConstructorInstantiationDemo instance = Whitebox.invokeConstructor(PrivateConstructorInstantiationDemo.class, new Class>[]{Integer.class}, 43);