Как повторно инициализировать статические финалы при юнит-тестировании - PullRequest
1 голос
/ 14 ноября 2008

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

Как это было бы возможно? Нужно ли использовать какой-то пользовательский загрузчик классов?

Переменная инициализируется как -

 static final CountdownLatch latch = new CountdownLatch(1);

Ответы [ 7 ]

5 голосов
/ 14 ноября 2008

Конечно, вы можете взломать его с помощью рефлексии или загрузки классов, но «на вашем месте я бы здесь не начинал». Изменяемые статики действительно злые (даже те, которые называются синглетонами). Таким образом, проектируйте код лучше, используя «параметризацию сверху» - передавайте объект тем, кто в них нуждается, вместо того, чтобы делать что-то аппаратное или использовать службу каталогов.

3 голосов
/ 17 ноября 2008

Вы можете изменить статические финалы, начиная с JDK 1.5 через отражение. (см. эту ссылку для примера кода) ... но я бы посоветовал вам этого не делать. Фактически это показало в прошлом, что статических переменных следует избегать, если это возможно. Commons Logging является хорошим примером. (см. объяснение здесь ).

Так что, если возможно, избавьтесь от final и даже static . Если это не вариант, вы можете написать вспомогательную функцию, которая делает это с помощью отражения. Но это, безусловно, худший вариант.

2 голосов
/ 14 ноября 2008

Один (не очень эффективный) подход, предполагающий, что вы используете junit и ant.

Вы можете создать отдельный класс для каждого метода тестирования, а затем использовать режим вилки perTest.

В документации по Junit указано:

Управляет количеством создаваемых виртуальных машин Java, если вы хотите выполнить несколько тестов. Возможные значения: «perTest» (по умолчанию), «perBatch» и «Once». «Once» создает только одну виртуальную машину Java для всех тестов, тогда как «perTest» создает новую VM для каждого класса TestCase. perBatch создает виртуальную машину для каждого вложенного , а один собирает все вложенные . Обратите внимание, что только тесты с одинаковыми настройками filtertrace, haltonerror, haltonfailure, errorproperty и failproperty могут совместно использовать виртуальную машину, поэтому даже если вы установили forkmode на «один раз», Ant, возможно, придется создать более одной виртуальной машины Java. Этот атрибут игнорируется для тестов, которые не вставляются в новую виртуальную машину Java. начиная с Ant 1.6.2

1 голос
/ 14 ноября 2008

Как вы инициализируете статическую переменную final в первую очередь?

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

Пример: static final int number = getNumber ();

Путем насмешки метода getNumber (), возвращающего желаемое значение, вы можете управлять переменной 'number'.

0 голосов
/ 15 ноября 2008

Статические финалы являются константами, это означает, что они не изменяемы. Почему вы тестируете их с разными значениями?

Хорошая статическая конечная переменная - это некоторая информация о вашей среде. Например, переменная с вашей ОС. Вы даже не измените это в тестировании. В этом случае вам нужно протестировать на разных машинах (или хотя бы виртуальных машинах).

Но вы хотите проверить эту переменную с другими значениями. Таким образом, кажется, что один из модификаторов здесь неправильный, статический или конечный, один из них не соответствует семантике, которая вам нужна, иначе вы не захотите тестировать его с другими значениями.

Можете ли вы предоставить более подробную информацию о проблеме?

0 голосов
/ 14 ноября 2008

Редактирование комментария для пояснения того, что рассматриваемая переменная является статической и, следовательно, существует один раз в JVM.

Переменные, помеченные final , изменяются только один раз, что, по-видимому, происходит один раз в разных тестах. Если вы используете JUnit, почему бы не создавать новый экземпляр класса при каждом вызове setup (), который сам по себе вызывается перед каждым тестом. Это было бы самым быстрым и наиболее представительным в вашей ситуации.

0 голосов
/ 14 ноября 2008

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...