Arquillian Graphene @Location placeholder
Я изучаю Arquillian прямо сейчас, и мне интересно, как создать страницу с заполнителем внутри пути. Например:
@Location("/posts/{id}")
public class BlogPostPage {
public String getContent() {
// ...
}
}
или же
@Location("/posts/{name}")
@Location("/specific-page?requiredParam={value}")
Я безуспешно искал ответ на справочники по графину и аркиллиану. Я использовал библиотеку из другого языка, которая поддерживает объекты страницы, но она имеет встроенную поддержку заполнителей.
2 ответа
Это невозможно в настоящее время в графене. Я создал ARQGRA-500.
Теперь можно расширить графен для добавления динамических параметров. Вот как. (Аркиллиан 1.1.10. Финал, Графен 2.1.0. Финал.)
Создать интерфейс.
import java.util.Map;
public interface LocationParameterProvider {
Map<String, String> provideLocationParameters();
}
Создайте пользовательский LocationDecider для замены соответствующего графена. Я заменяю HTTP. Этот Decider добавит параметры местоположения в URI, если увидит, что тестовый объект реализует наш интерфейс.
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.Map;
import java.util.Map.Entry;
import org.jboss.arquillian.core.api.Instance;
import org.jboss.arquillian.core.api.annotation.Inject;
import org.jboss.arquillian.graphene.location.decider.HTTPLocationDecider;
import org.jboss.arquillian.graphene.spi.location.Scheme;
import org.jboss.arquillian.test.spi.context.TestContext;
public class HTTPParameterizedLocationDecider extends HTTPLocationDecider {
@Inject
private Instance<TestContext> testContext;
@Override
public Scheme canDecide() {
return new Scheme.HTTP();
}
@Override
public String decide(String location) {
String uri = super.decide(location);
// not sure, how reliable this method of getting the current test object is
// if it breaks, there is always a possibility of observing
// org.jboss.arquillian.test.spi.event.suite.TestLifecycleEvent's (or rather its
// descendants) and storing the test object in a ThreadLocal
Object testObject = testContext.get().getActiveId();
if (testObject instanceof LocationParameterProvider) {
Map<String, String> locationParameters =
((LocationParameterProvider) testObject).provideLocationParameters();
StringBuilder uriParams = new StringBuilder(64);
boolean first = true;
for (Entry<String, String> param : locationParameters.entrySet()) {
uriParams.append(first ? '?' : '&');
first = false;
try {
uriParams.append(URLEncoder.encode(param.getKey(), "UTF-8"));
uriParams.append('=');
uriParams.append(URLEncoder.encode(param.getValue(), "UTF-8"));
} catch (UnsupportedEncodingException e) {
throw new RuntimeException(e);
}
}
uri += uriParams.toString();
}
return uri;
}
}
Наш LocationDecider должен быть зарегистрирован для переопределения графена.
import org.jboss.arquillian.core.spi.LoadableExtension;
import org.jboss.arquillian.graphene.location.decider.HTTPLocationDecider;
import org.jboss.arquillian.graphene.spi.location.LocationDecider;
public class MyArquillianExtension implements LoadableExtension {
@Override
public void register(ExtensionBuilder builder) {
builder.override(LocationDecider.class, HTTPLocationDecider.class,
HTTPParameterizedLocationDecider.class);
}
}
MyArquillianExtension должен быть зарегистрирован через SPI, поэтому создайте необходимый файл в ваших ресурсах тестирования, например, для меня путь к файлу src/test/resources/META-INF/services/org.jboss.arquillian.core.spi.LoadableExtension
, Файл должен содержать полное имя класса MyArquillianExtension.
И это все. Теперь вы можете указать параметры местоположения в тесте.
import java.util.HashMap;
import java.util.Map;
import org.jboss.arquillian.graphene.page.InitialPage;
import org.jboss.arquillian.graphene.page.Location;
import org.junit.Test;
public class TestyTest implements LocationParameterProvider {
@Override
public Map<String, String> provideLocationParameters() {
Map<String, String> params = new HashMap<>();
params.put("mykey", "myvalue");
return params;
}
@Test
public void test(@InitialPage TestPage page) {
}
@Location("MyTestView.xhtml")
public static class TestPage {
}
}
Я сосредоточился именно на параметрах, но, надеюсь, это проложит путь для других динамических манипуляций с путями.
Конечно это не исправит Graphene.goTo
API. Это означает, что перед использованием goTo вы должны предоставить параметры с помощью этого обходного метода provideLocationParameters. Это странно. Вы можете создать свой собственный альтернативный API, перейти к тому, который принимает параметры, и изменить свой LocationDecider для поддержки других ParameterProviders.
AFAIK нет ничего подобного, реализованного в графене. Если честно, я не уверен, как это должно себя вести - как бы вы передали значения...?
Кроме того, я думаю, что это также может быть ограничено возможностями аннотации Java /questions/36394232/znacheniya-annotatsij-java-predostavlyayutsya-v-dinamicheskom-rezhime/36394239#36394239