Arquillian mixed mode not working on TestNG

169 Views Asked by At

I am trying to run a test suite in mixed mode using Arquillian and TestNG.

Based on the documentation here: http://arquillian.org/arquillian-core/#mixed-mode

I would expect to be able to write my test like this:

public class ExampleTest extends Arquillian {
    
    @Deployment
    public static EnterpriseArchive createDeployment() {
      return ear; //contains both web and jar modules
    }
    
    @Test @RunAsClient
    public void testA(@ArquillianResource(TestServlet.class) URL baseUrl) {
        runTest(baseURL);
    }

    @EJB //Used for container tests
    public TestBean bean;
    
    @Test 
    public void testB() throws Throwable {
        bean.runTest();
    }
}

In this case, testA fails because TestNG does not allow test methods to have injected parameters.

If instead, I inject the test URL as a field like this:

public class ExampleTest extends Arquillian {

    @Deployment
    public static EnterpriseArchive createDeployment() {
      return ear; //contains both web and jar modules
    }
    
    @ArquillianResource(TestServlet.class) //Used for client tests
    URL baseUrl

    @Test @RunAsClient
    public void testA() {
        runTest(baseURL);
    }

    @EJB //Used for container tests
    public TestBean bean;

    @Test 
    public void testB() throws Throwable {
        bean.runTest();
    }
}

Then testB will fail because it was not able to inject the URL field even though it was not annotated as a client-side test:

Could not lookup value for field java.net.URL ExampleTest.baseURL

java.lang.RuntimeException: Could not lookup value for field java.net.URL ExampleTest.baseURL
at org.jboss.arquillian.test.impl.enricher.resource.ArquillianResourceTestEnricher.enrich(ArquillianResourceTestEnricher.java:68)
at org.jboss.arquillian.test.impl.TestInstanceEnricher.enrich(TestInstanceEnricher.java:51)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:566)
...
Caused by: java.lang.RuntimeException: java.lang.TypeNotPresentException: Type TestServlet not present
at org.jboss.arquillian.protocol.servlet5.runner.ServletCommandService.execute(ServletCommandService.java:42)
at org.jboss.arquillian.container.test.impl.enricher.resource.ContainerURLResourceProvider.lookup(ContainerURLResourceProvider.java:46)
at org.jboss.arquillian.test.impl.enricher.resource.ArquillianResourceTestEnricher.lookup(ArquillianResourceTestEnricher.java:116)
at org.jboss.arquillian.test.impl.enricher.resource.ArquillianResourceTestEnricher.enrich(ArquillianResourceTestEnricher.java:66)
... 95 more
Caused by: java.lang.TypeNotPresentException: Type TestServlet not present
at java.base/sun.reflect.annotation.TypeNotPresentExceptionProxy.generateException(TypeNotPresentExceptionProxy.java:46)
at java.base/sun.reflect.annotation.AnnotationInvocationHandler.invoke(AnnotationInvocationHandler.java:86)
at com.sun.proxy.$Proxy37.value(Unknown Source)
at org.jboss.arquillian.container.test.impl.enricher.resource.URLResourceProvider.locateURL(URLResourceProvider.java:67)
at org.jboss.arquillian.container.test.impl.enricher.resource.URLResourceProvider.doLookup(URLResourceProvider.java:51)
at org.jboss.arquillian.container.test.impl.enricher.resource.OperatesOnDeploymentAwareProvider.runInContainerContext(OperatesOnDeploymentAwareProvider.java:130)
at org.jboss.arquillian.container.test.impl.enricher.resource.OperatesOnDeploymentAwareProvider.runInDeploymentContext(OperatesOnDeploymentAwareProvider.java:93)
at org.jboss.arquillian.container.test.impl.enricher.resource.OperatesOnDeploymentAwareProvider.lookup(OperatesOnDeploymentAwareProvider.java:59)
at org.jboss.arquillian.container.test.impl.enricher.resource.RemoteResourceCommandObserver.lookup(RemoteResourceCommandObserver.java:31)
...
Caused by: java.lang.ClassNotFoundException: TestServlet
at java.base/java.lang.Class.forNameImpl(Native Method)
at java.base/java.lang.Class.forName(Class.java:425)
at java.base/sun.reflect.generics.factory.CoreReflectionFactory.makeNamedType(CoreReflectionFactory.java:114)
at java.base/sun.reflect.generics.visitor.Reifier.visitClassTypeSignature(Reifier.java:125)
at java.base/sun.reflect.generics.tree.ClassTypeSignature.accept(ClassTypeSignature.java:49)
at java.base/sun.reflect.annotation.AnnotationParser.parseSig(AnnotationParser.java:440)
at java.base/sun.reflect.annotation.AnnotationParser.parseClassValue(AnnotationParser.java:421)
at java.base/sun.reflect.annotation.AnnotationParser.parseMemberValue(AnnotationParser.java:350)
at java.base/sun.reflect.annotation.AnnotationParser.parseAnnotation2(AnnotationParser.java:287)
at java.base/sun.reflect.annotation.AnnotationParser.parseAnnotations2(AnnotationParser.java:121)
at java.base/sun.reflect.annotation.AnnotationParser.parseAnnotations(AnnotationParser.java:73)
at java.base/java.lang.reflect.Field.declaredAnnotations(Field.java:1175)
at java.base/java.lang.reflect.Field.declaredAnnotations(Field.java:1173)
at java.base/java.lang.reflect.Field.getAnnotation(Field.java:1142)
at java.base/java.lang.reflect.AnnotatedElement.isAnnotationPresent(AnnotatedElement.java:274)
at java.base/java.lang.reflect.AccessibleObject.isAnnotationPresent(AccessibleObject.java:517)
at org.jboss.arquillian.testenricher.ejb.SecurityActions$3.run(SecurityActions.java:237)
at org.jboss.arquillian.testenricher.ejb.SecurityActions$3.run(SecurityActions.java:231)
at java.base/java.security.AccessController.doPrivileged(AccessController.java:678)
at org.jboss.arquillian.testenricher.ejb.SecurityActions.getFieldsWithAnnotation(SecurityActions.java:231)
at org.jboss.arquillian.testenricher.ejb.EJBInjectionEnricher.injectClass(EJBInjectionEnricher.java:101)
...

Is mixed-mode just not supported for TestNG or am I doing something wrong?

Thank you for your help!

1

There are 1 best solutions below

0
decoiro On

From the documentation Arquillian documentation - Mixed Mode:

The effect of the different run modes depends on the DeployableContainer used. Both modes might seem to behave the same in some Embedded containers, but you should avoid mixing your internal and external tests. One thing is that they should test different aspects of your application and different use-cases, another is that you will miss the benefits of switching DeployableContainers and run the same tests suite against a remote server if you do.

Maybe that's the problem, your EAR is mixing the context. Perhaps you might have to use a WAR, if possible.

Stupid question, that might do the trick, did you try to force the order of your tests? Running the as-client as the last test case might solve your problem.