Ответ 1
Да, вы можете использовать отражения для доступа к приватным переменным. Хотя это не очень хорошая идея.
Проверьте это:
http://en.wikibooks.org/wiki/Java_Programming/Reflection/Accessing_Private_Features_with_Reflection
Мне назначена задача модульного тестирования класса, с которым я никогда не работал напрямую с JUnit, и мне строго запрещено изменять код в пакете. Обычно это не проблема, так как большинство наших модульных тестов предназначены только для функциональности и согласованности ввода/вывода, что можно сделать просто за счет запуска подпрограмм и проверки их возвращаемых значений.
Однако иногда возникает необходимость проверить приватную переменную внутри класса или непосредственно редактировать приватную переменную, чтобы проверить внутреннее поведение. Есть ли способ получить доступ к ним, будь то через JUnit или любым другим способом, для целей модульного тестирования без фактического изменения какого-либо кода в исходном исходном пакете? И если нет, то как программисты справляются с этой проблемой в реальном мире, где тестером модуля может быть не тот человек, что кодер?
Да, вы можете использовать отражения для доступа к приватным переменным. Хотя это не очень хорошая идея.
Проверьте это:
http://en.wikibooks.org/wiki/Java_Programming/Reflection/Accessing_Private_Features_with_Reflection
Прежде всего, вы сейчас плохо себя чувствуете - имея задачу написать тесты для кода, который вы изначально не создали и без каких-либо изменений, - кошмар! Поговорите с вашим боссом и объясните, что невозможно проверить код, не делая его "проверяемым". Чтобы сделать код тестируемым, вы обычно делаете некоторые важные изменения;
Относительно частных переменных. Вы на самом деле никогда не должны этого делать. Цель тестирования частных переменных - это первый сигнал о том, что что-то не так с дизайном сейчас. Частные переменные являются частью реализации, тесты должны сосредоточиться на поведении, а не на деталях реализации.
Иногда частное поле открывается с помощью некоторого getter. Я делаю это, пытаясь избежать как можно большего (отметьте в комментариях, например, "используется для тестирования" ).
Поскольку у вас нет возможности изменить код, я не вижу возможности (я имею в виду реальную возможность, а не как Reflection hacks и т.д.) для проверки частной переменной.
Reflection например:.
public class PrivateObject {
private String privateString = null;
public PrivateObject(String privateString) {
this.privateString = privateString;
}
}
PrivateObject privateObject = new PrivateObject("The Private Value");
Field privateStringField = PrivateObject.class.
getDeclaredField("privateString");
privateStringField.setAccessible(true);
String fieldValue = (String) privateStringField.get(privateObject);
System.out.println("fieldValue = " + fieldValue);
Вот статья, которая решает именно эту проблему (в частности, тестирование):
Несмотря на опасность указания очевидности: с помощью unit test вы хотите проверить правильное поведение объекта - и это определяется с точки зрения его открытого интерфейса. Вас не интересует, как объект выполняет эту задачу - это деталь реализации и не видна снаружи. Это одна из причин, почему OO была изобретена: детали реализации скрыты. Поэтому нет смысла тестировать частных членов. Вы сказали, что вам нужно 100% покрытие. Если есть фрагмент кода, который не может быть протестирован с использованием открытого интерфейса объекта, то этот фрагмент кода на самом деле никогда не вызывается и, следовательно, не может быть проверен. Удалите его.
Я не могу сказать, нашел ли вы специальный код случая, который требует проверки на закрытые поля. Но по моему опыту вам никогда не нужно проверять что-то частное - всегда публичное. Может быть, вы могли бы привести пример некоторого кода, где вам нужно проверить личное?
Если вы создаете тестовые классы в отдельной папке, которую затем добавляете в свой путь сборки,
Затем вы можете сделать тестовый класс внутренним классом тестируемого класса, правильно используя пакет, чтобы установить пространство имен. Это дает ему доступ к частным полям и методам.
Но не забудьте удалить папку из пути сборки для вашей сборки выпуска.