Tôi gặp vấn đề tương tự khi không đặt giá trị riêng tư vì Mockito không gọi siêu kiến trúc sư. Đây là cách tôi tăng cường chế giễu với sự phản ánh.
Đầu tiên, tôi đã tạo một lớp TestUtils có chứa nhiều tiện ích hữu ích bao gồm các phương thức phản chiếu này. Truy cập phản ánh là một chút khó khăn để thực hiện mỗi lần. Tôi đã tạo ra các phương thức này để kiểm tra mã trên các dự án, vì lý do này hay lý do khác, không có gói chế nhạo và tôi không được mời đưa vào nó.
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);
}
}
}
Sau đó, tôi có thể kiểm tra lớp với một biến riêng tư như thế này. Điều này rất hữu ích để chế nhạo sâu trong các cây lớp mà bạn không kiểm soát được.
@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
}
Tôi đã sửa đổi mã của tôi từ dự án thực tế của tôi ở đây, trong trang. Có thể có một hoặc hai vấn đề biên dịch. Tôi nghĩ rằng bạn có được ý tưởng chung. Hãy lấy mã và sử dụng nó nếu bạn thấy nó hữu ích.