Подтвердить что ты не робот

JUnit Тестирование частных переменных?

Мне назначена задача модульного тестирования класса, с которым я никогда не работал напрямую с JUnit, и мне строго запрещено изменять код в пакете. Обычно это не проблема, так как большинство наших модульных тестов предназначены только для функциональности и согласованности ввода/вывода, что можно сделать просто за счет запуска подпрограмм и проверки их возвращаемых значений.

Однако иногда возникает необходимость проверить приватную переменную внутри класса или непосредственно редактировать приватную переменную, чтобы проверить внутреннее поведение. Есть ли способ получить доступ к ним, будь то через JUnit или любым другим способом, для целей модульного тестирования без фактического изменения какого-либо кода в исходном исходном пакете? И если нет, то как программисты справляются с этой проблемой в реальном мире, где тестером модуля может быть не тот человек, что кодер?

4b9b3361

Ответ 2

Прежде всего, вы сейчас плохо себя чувствуете - имея задачу написать тесты для кода, который вы изначально не создали и без каких-либо изменений, - кошмар! Поговорите с вашим боссом и объясните, что невозможно проверить код, не делая его "проверяемым". Чтобы сделать код тестируемым, вы обычно делаете некоторые важные изменения;

Относительно частных переменных. Вы на самом деле никогда не должны этого делать. Цель тестирования частных переменных - это первый сигнал о том, что что-то не так с дизайном сейчас. Частные переменные являются частью реализации, тесты должны сосредоточиться на поведении, а не на деталях реализации.

Иногда частное поле открывается с помощью некоторого getter. Я делаю это, пытаясь избежать как можно большего (отметьте в комментариях, например, "используется для тестирования" ).

Поскольку у вас нет возможности изменить код, я не вижу возможности (я имею в виду реальную возможность, а не как Reflection hacks и т.д.) для проверки частной переменной.

Ответ 3

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);

Ответ 5

Несмотря на опасность указания очевидности: с помощью unit test вы хотите проверить правильное поведение объекта - и это определяется с точки зрения его открытого интерфейса. Вас не интересует, как объект выполняет эту задачу - это деталь реализации и не видна снаружи. Это одна из причин, почему OO была изобретена: детали реализации скрыты. Поэтому нет смысла тестировать частных членов. Вы сказали, что вам нужно 100% покрытие. Если есть фрагмент кода, который не может быть протестирован с использованием открытого интерфейса объекта, то этот фрагмент кода на самом деле никогда не вызывается и, следовательно, не может быть проверен. Удалите его.

Ответ 6

Я не могу сказать, нашел ли вы специальный код случая, который требует проверки на закрытые поля. Но по моему опыту вам никогда не нужно проверять что-то частное - всегда публичное. Может быть, вы могли бы привести пример некоторого кода, где вам нужно проверить личное?

Ответ 7

Если вы создаете тестовые классы в отдельной папке, которую затем добавляете в свой путь сборки,

Затем вы можете сделать тестовый класс внутренним классом тестируемого класса, правильно используя пакет, чтобы установить пространство имен. Это дает ему доступ к частным полям и методам.

Но не забудьте удалить папку из пути сборки для вашей сборки выпуска.