Статьи

Arquillan + Java 8

В Java 8 реализовано много новых языковых улучшений для облегчения жизни разработчика. На мой взгляд, одна из главных особенностей Java 8 состоит в том, что в некоторых ситуациях разработанный код выглядит более красиво, чем при использовании предыдущих подходов, и я имею в виду ссылки на Lambdas и Method. Этот пост не об изучении этих функций Java 8, а о том, как применять их в платформе Arquillian .

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

Объединить библиотеки внутри JavaArchive

<0> Чтобы написать тесты с
Arquillian, вам нужно создать файл развертывания программно (jar, war или ear). Это достигается с помощью
Shrinkwrap . Ваш файл развертывания иногда требует, чтобы вы добавили к нему некоторые внешние зависимости. Типичный пример — когда вы создаете
WebArchive и вам нужно добавить некоторые зависимости в
WEB-INF / lib . В данном случае это легко , потому что там
Веб — архив класса есть метод , называемый
addAsLibraries , который в основном складывает данные банки в пути библиотек.

Но что происходит, когда ваш файл развертывания является файлом JAR? Затем вам нужно объединить каждую библиотеку внутри объекта JavaArchive с помощью метода слияния .

private static JavaArchive mergeHibernate(JavaArchive javaArchive) {
    JavaArchive[] javaArchives = Maven.resolver().resolve("org.hibernate:hibernate-entitymanager:4.2.15.Final").withTransitivity().as(JavaArchive.class);
    for(JavaArchive hibernateDep: javaArchives) {
        javaArchive.merge(hibernateDep);
    }
    return javaArchive;
}

Это способ сделать это, но в Java 8 вы можете использовать функции foreach и ссылки на методы .

private static JavaArchive mergeHibernate(JavaArchive javaArchive) {
    JavaArchive[] javaArchives = Maven.resolver().resolve("org.hibernate:hibernate-entitymanager:4.2.15.Final").withTransitivity().as(JavaArchive.class);
    Arrays.stream(javaArchives).forEach(javaArchive::merge);
    
    return javaArchive;
}

Обратите внимание, что мы конвертируем массив в поток, чтобы мы могли вызывать функцию foreach. В версии 2.2.0 ShrinkWrap Resolver вы сможете получать зависимости в виде списка, поэтому вы сможете получать поток без какого-либо преобразования. Следующим важным моментом является то, что мы используем функцию ссылки на метод для объединения всех зависимостей. Теперь с помощью одной строки мы можем объединить все зависимости.

Создание пользовательских активов

Arquillian использует ShrinkWrap для создания файла развертывания и добавления ресурсов внутри. Эти ресурсы добавляются с помощью любого из методов, предоставляемых API, таких как add , addClass , addAsManifestReource  и так далее. Эти методы могут получить в качестве первого параметра Актив . Asset — это интерфейс, который содержит только один метод openStream, который возвращает InputStream . Активы используются для настройки содержимого файла, который будет добавлен в файл развертывания. 

Например:

archive.add(new StringAsset("My txt file"), "hello.txt");

ShrinkWrap поставляется с некоторыми уже определенными активами, такими как Url, String, Byte, Class, … но иногда вам может понадобиться реализовать свой собственный актив.

ShrinkWrap.create(JavaArchive.class).addAsManifestResource( 
                                          new Asset() {
                                             public InputStream openStream() {
                                                  return new CheckedInputStream(urlInputStream, crc32)
                                             }
                                          }, 
                                     "persistence.xml");

В этом случае мы используем внутренний класс, но поскольку класс Asset можно считать функциональным интерфейсом (только один абстрактный метод), мы можем использовать Lambdas, чтобы избежать внутреннего класса.

Так много простых и удобочитаемых.

Разбор HTML-таблиц

Если вы используете Arquillian Drone или Arquillian Graphene, вы будете использовать некоторые классы WebDriver Selenium для получения элементов веб-страницы. Иногда вам нужно проверить столбцы и таблицу HTML, и в этом случае вы можете получить много шаблонного кода, повторяющегося по столбцам и строкам для проверки, содержащего правильные значения.

Ваш код до Java 8 будет выглядеть примерно так:

List<WebElement> elements = session.findElements(xpath("//table/tbody/tr/td/span[@class='title']"));

List<String> columnValues = new ArrayList<String>();
for(WebElement webElement : elements) {
  columnValues.add(webElement.getText());
}

return columnValues;

Но в Java 8 с добавлением потокового API код становится намного проще и удобочитаемее:

List<WebElement> elements = session.findElements(xpath("//table/tbody/tr/td/span[@class='title']"));
return elements.stream().map(WebElement::getText).collect(Collectors.toList());

Как видите, код довольно компактен. То, что мы делаем здесь, это в первую очередь получение всех веб-элементов заголовка колонки , никаких новостей здесь. Но тогда потоковое API вступает в игру. Сначала мы создаем поток из списка, вызывая метод stream . Затем мы вызываем метод getText из всех WebElements, представленных в списке. И, наконец, возвращается список строк, который фактически является списком содержимого всех строк заголовка столбца. 

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

Итак, как вы можете видеть, Java 8 может использоваться не только в бизнес-коде, но и в тестах.

Мы продолжаем учиться,

Алекс.