Это ваш выбор. В архиве веб-приложений Java (WAR) есть три способа:
. Чтобы вы могли загрузить его с помощью ClassLoader#getResourceAsStream()
с относительным путем classpath:
ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
InputStream input = classLoader.getResourceAsStream("foo.properties");
// ...
Properties properties = new Properties();
properties.load(input);
Здесь foo.properties
предполагается, что они будут помещены в один из корней, которые покрываются классом по умолчанию для webapp, например webapp /WEB-INF/lib
и /WEB-INF/classes
, /lib
сервера или JDK / JRE /lib
. Если файл свойств является webapp-специфическим, лучше всего поместить его в /WEB-INF/classes
. Если вы разрабатываете стандартный проект WAR в среде IDE, поместите его в папку src
(исходную папку проекта). Если вы используете проект Maven, поместите его в папку /main/resources
.
Вы также можете поместить его где-то за пределы пути по умолчанию и добавить свой путь к пути к классам на сервере приложений. Например, Tomcat вы можете настроить его как свойство shared.loader
в Tomcat/conf/catalina.properties
.
Если вы поместили foo.properties
в структуру пакета Java, например com.example
, вам необходимо загрузить его как показано ниже
ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
InputStream input = classLoader.getResourceAsStream("com/example/foo.properties");
// ...
Обратите внимание, что этот путь загрузчика класса контекста не должен начинаться с /
. Только когда вы используете «относительный» загрузчик классов, например SomeClass.class.getClassLoader()
, вам действительно нужно запустить его с помощью /
.
ClassLoader classLoader = getClass().getClassLoader();
InputStream input = classLoader.getResourceAsStream("/com/example/foo.properties");
// ...
Однако видимость файла свойств зависит затем на класс загрузчика, о котором идет речь. Это видно только для того же загрузчика классов, что и тот, который загружал класс. Таким образом, если класс загружается, например, server common classloader вместо загрузчика классов webapp, а файл свойств находится внутри самого webapp, а затем он невидим. Загрузчик контекстного класса - это ваша самая безопасная ставка, поэтому вы можете поместить файл свойств «всюду» в путь к классам и / или вы намерены переопределить сервер, предоставленный с помощью webapp.
Чтобы вы могли загрузить его с помощью ServletContext#getResourceAsStream()
с относительным путем webcontent:
InputStream input = getServletContext().getResourceAsStream("/WEB-INF/foo.properties");
// ...
Обратите внимание, что я продемонстрировал для размещения файла в папке /WEB-INF
, иначе он был бы общедоступным для любого веб-браузера. Также обратите внимание, что ServletContext
находится в любом классе HttpServlet
, доступном только унаследованным GenericServlet#getServletContext()
и в Filter
на FilterConfig#getServletContext()
. Если вы не находитесь в классе сервлета, его обычно можно вводить через @Inject
.
. Чтобы загрузить его обычным способом java.io
с использованием пути к файловой системе с абсолютным локальным диском:
InputStream input = new FileInputStream("/absolute/path/to/foo.properties");
// ...
Обратите внимание на важность использования абсолютный путь. Относительные пути локальной файловой системы на диске - это абсолютное отсутствие в веб-приложении Java EE. См. Также первую ссылку «См. Также».
Просто взвешивайте преимущества / недостатки в своих собственных мнениях ремонтопригодность.
Если файлы свойств «статические» и никогда не должны меняться во время выполнения, вы можете сохранить их в WAR.
Если вы предпочитаете редактировать файлы свойств извне веб-приложение без необходимости перестраивать и переустанавливать WAR каждый раз, а затем помещать его в путь класса вне проекта (при необходимости добавить каталог в путь к классам).
Если вы предпочитаете иметь возможность редактировать файлы свойств программно из веб-приложения с помощью метода Properties#store()
, выведите его за пределы веб-приложения. Поскольку для Properties#store()
требуется Writer
, вы не можете использовать путь к файловой системе диска. Этот путь, в свою очередь, может быть передан в веб-приложение как аргумент VM или системное свойство. В качестве меры предосторожности никогда не используйте getRealPath()
. Все изменения в папке развертывания будут потеряны при повторном развертывании по той простой причине, что изменения не будут возвращены в исходный файл WAR.
Это уже было решено в ответе Рана на аналогичный вопрос SO. Цитата Ран:
Начиная с версии 2.5.7, NUnit позволяет Teardown обнаруживать, не прошел ли последний тест. Новый класс TestContext позволяет тестам получать доступ к информации о себе, включая TestStauts.
Для получения более подробной информации, пожалуйста, обратитесь к http://nunit.org/?p=releaseNotes&r=2.5.7
[TearDown]
public void TearDown()
{
if (TestContext.CurrentContext.Result.Status == TestStatus.Failed)
{
PerformCleanUpFromTest();
}
}
ИМХО логика разрушения должна быть независимой от результатов испытаний.
В идеале, вам следует избегать полностью использовать установку и демонтаж, al xunit.net. См. здесь для получения дополнительной информации.
звучит как опасная идея, если только это не интеграционный тест, скажем, с данными, которые нужно удалить. Почему бы не сделать это в самом тесте?
Очевидно, что в классе может быть установлен частный флаг.
Только если вы делаете это вручную. Фактически, вы даже не узнаете, какие тесты собираются запускать. В NUnit IDE можно включить одни тесты и отключить другие. Если вы хотите узнать, был ли запущен какой-то конкретный тест, вы можете включить в свой тестовый класс такой код:
enum TestStateEnum { DISABLED, FAILED, SUCCEDED };
TestStateEnum test1State = TestStateEnum.DISABLED;
[Test]
void Test1()
{
test1State = TestStateEnum.FAILED; // On the beginning of your test
...
test1State = TestStateEnum.SUCCEDED; // On the End of your Test
}
Затем вы можете проверить переменную test1State. Если тест выдает исключение, он не устанавливает SUCCEDED. вы также можете поместить это в блок try catch finally в ваших тестах с немного другой логикой:
[Test]
void Test1()
{
test1State = TestStateEnum.SUCCEDED; // On the beginning of your test
try
{
... // Your Test
}
catch( Exception )
{
test1State = TestStateEnum.FAILED;
throw; // Rethrows the Exception
}
}