У меня есть проект знатока мультимодуля. В сохранять модуле у меня есть много файлов данных XML-файлов, которые ссылаются на DTD:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE myapp-data SYSTEM "myapp-data.dtd" >
<dataset>
.....omitted for brevity....
</dataset>
DTD хранится в том же каталоге с XML-файлами, и даже Eclipse сообщает об этих XML-файлах как допустимых.
Однако то, когда я запускаю приложение, DBUnit FlatXMLDataSet выдает исключение FileNotFound, потому что это не может, определило местоположение DTD. Это, по-видимому, ищет DTD в корневом каталоге проекта (например, myproject/). Я ожидал бы, что это будет искать DTD в том же каталоге как сам XML-файл (например, myproject/persist/target/test-data).
Смотря на исходный код DBUnit, это говорит следующее об этом "Относительный uri DOCTYPE, разрешены от текущей работы dicrectory".
Что хороший путь состоит в том, чтобы зафиксировать это?
OK, кажется, я разобрался с этим. Слава богу, что есть открытый исходный код.
В FlatXmlDataSetBuilder есть метод, который принимает поток к DTD. Это безумие, что это публичный метод IMO, но опять же, это безумие, что DBUnit не ищет файл dtd в том же каталоге, что и XML. Итак, вот оно:
String dtdResourceName = "classpath:test-data/myapp-data.dtd";
Resource res = applicationContext.getResource(dtdResourceName);
builder.setMetaDataSetFromDtd(res.getInputStream());
Теперь я оставляю декларацию DOCTYPE с dtd в том же каталоге, что и XML, и использую этот хак, чтобы обмануть DBUnit и заставить его делать то, что нужно.
Всегда используйте правильные переменные для доступа к специальным каталогам, потому что многомодульные сборки имеют рабочий каталог, отличный от локальных:
Итак,
mydir
используйте $ {project.basedir} / mydir
target / mydir
используйте $ {project. build.directory} / mydir
target / classes / mydir
используйте $ {project.build.outputDirectory} / mydir
Эти переменные всегда оцениваются для текущего проекта, не важно откуда он вызван. Вот Обзор переменных POM (не полный, но там есть самое важное)
Кроме того, если вы когда-нибудь захотите выполнить отладку в интерактивном стиле запроса, поможет: оценить Пригодится mojo :
просто вызовите
mvn help:evaluate
, и вам будет предложено ввести выражение. Если вы введете выражение, например $ {project.build.plugins [0]}
, будет отображен объединенный дом для указанного элемента
РЕДАКТИРОВАТЬ:
хорошо, теперь я думаю, что вижу проблему. тогда почему бы просто не сослаться на каталог в xml:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE myapp-data SYSTEM "target/test-classes/myapp-data.dtd" >
Я знаю, что это некрасиво, но он должен работать, многомодульный или нет. текущим каталогом для модульных тестов всегда является текущий каталог $ {project.basedir}, а не каталог родительского проекта.