Mockitoがスーパーコンストラクターを呼び出さないため、プライベート値が設定されないという同じ問題がありました。これが私が反射でモックをどのように増強するかです。
最初に、これらのリフレクションメソッドを含む多くの便利なユーティリティを含むTestUtilsクラスを作成しました。リフレクションアクセスは、毎回実装するのが少し面倒です。私はこれらのメソッドを作成して、何らかの理由でモックパッケージがなく、インクルードするよう招待されなかったプロジェクトでコードをテストしました。
public class TestUtils {
// get a static class value
public static Object reflectValue(Class<?> classToReflect, String fieldNameValueToFetch) {
try {
Field reflectField = reflectField(classToReflect, fieldNameValueToFetch);
reflectField.setAccessible(true);
Object reflectValue = reflectField.get(classToReflect);
return reflectValue;
} catch (Exception e) {
fail("Failed to reflect "+fieldNameValueToFetch);
}
return null;
}
// get an instance value
public static Object reflectValue(Object objToReflect, String fieldNameValueToFetch) {
try {
Field reflectField = reflectField(objToReflect.getClass(), fieldNameValueToFetch);
Object reflectValue = reflectField.get(objToReflect);
return reflectValue;
} catch (Exception e) {
fail("Failed to reflect "+fieldNameValueToFetch);
}
return null;
}
// find a field in the class tree
public static Field reflectField(Class<?> classToReflect, String fieldNameValueToFetch) {
try {
Field reflectField = null;
Class<?> classForReflect = classToReflect;
do {
try {
reflectField = classForReflect.getDeclaredField(fieldNameValueToFetch);
} catch (NoSuchFieldException e) {
classForReflect = classForReflect.getSuperclass();
}
} while (reflectField==null || classForReflect==null);
reflectField.setAccessible(true);
return reflectField;
} catch (Exception e) {
fail("Failed to reflect "+fieldNameValueToFetch +" from "+ classToReflect);
}
return null;
}
// set a value with no setter
public static void refectSetValue(Object objToReflect, String fieldNameToSet, Object valueToSet) {
try {
Field reflectField = reflectField(objToReflect.getClass(), fieldNameToSet);
reflectField.set(objToReflect, valueToSet);
} catch (Exception e) {
fail("Failed to reflectively set "+ fieldNameToSet +"="+ valueToSet);
}
}
}
次に、このようなプライベート変数を使用してクラスをテストできます。これは、ユーザーが制御できないクラスツリーの奥深くをモックする場合に役立ちます。
@Test
public void testWithRectiveMock() throws Exception {
// mock the base class using Mockito
ClassToMock mock = Mockito.mock(ClassToMock.class);
TestUtils.refectSetValue(mock, "privateVariable", "newValue");
// and this does not prevent normal mocking
Mockito.when(mock.somthingElse()).thenReturn("anotherThing");
// ... then do your asserts
}
ここのページで、実際のプロジェクトのコードを変更しました。コンパイルの問題が発生する可能性があります。あなたは一般的な考えを理解していると思います。コードを入手して、必要に応じて自由に使用してください。