helidon-io / helidon

Java libraries for writing microservices
https://helidon.io
Apache License 2.0
3.52k stars 564 forks source link

HelidonTest doesn’t allow preparatory steps #3928

Open tejo93 opened 2 years ago

tejo93 commented 2 years ago

Refactor HelidonTest to accommodate preparatory steps before Server starts and CDI loads

Environment Details


Problem Description

Currently the @BeforeEach method of junit gets executed after the Helidon Server is started and classes annotated with @ApplicationScoped are executed when using @HelidonTest(resetPerTest=true). This doesn’t give the liberty to do some preparatory steps in @BeforeEach to set some system properties or global variables which can be used in main class before the server starts. BeforeAll gives that liberty but it gets executed only once per test class. We want per test method. There is a workaround by using @AddConfig notation for each test case and set values, but requirement is not to tamper with the config properties and use system or global variables.

spericas commented 2 years ago

I suspect we have cases where @BeforeEach needs to be called after the server started (as it is now). Thus, this is likely not a refactoring but more like a new feature to support this use case.

jbescos commented 5 months ago

For the record.

The container starts at first place:

Thread [main] (Suspended (breakpoint at line 353 in io.helidon.microprofile.testing.junit5.HelidonJunitExtension))  
    io.helidon.microprofile.testing.junit5.HelidonJunitExtension.startContainer(java.util.List<io.helidon.microprofile.testing.junit5.AddBean>, java.util.List<io.helidon.microprofile.testing.junit5.AddExtension>, boolean) line: 353 
    io.helidon.microprofile.testing.junit5.HelidonJunitExtension.beforeAll(org.junit.jupiter.api.extension.ExtensionContext) line: 163  
    org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.lambda$invokeBeforeAllCallbacks$12(org.junit.jupiter.api.extension.BeforeAllCallback, org.junit.jupiter.api.extension.ExtensionContext) line: 395  

Then @BeforeAll is executed:


Thread [main] (Suspended (breakpoint at line 14 in io.helidon.microprofile.tests.testing.junit5.TestBefore))    
    io.helidon.microprofile.tests.testing.junit5.TestBefore.beforeAll() line: 14    
    java.lang.invoke.DirectMethodHandle$Holder.invokeStatic(java.lang.Object) line: not available   
    java.lang.invoke.LambdaForm$MH.0x00007f160430bc00.invoke(java.lang.Object, java.lang.Object) line: not available    
    java.lang.invoke.Invokers$Holder.invokeExact_MT(java.lang.Object, java.lang.Object, java.lang.Object) line: not available   
    jdk.internal.reflect.DirectMethodHandleAccessor.invokeImpl(java.lang.Object, java.lang.Object[]) line: 153  
    jdk.internal.reflect.DirectMethodHandleAccessor.invoke(java.lang.Object, java.lang.Object[]) line: 103  
    java.lang.reflect.Method.invoke(java.lang.Object, java.lang.Object...) line: 580    
    org.junit.platform.commons.util.ReflectionUtils.invokeMethod(java.lang.reflect.Method, java.lang.Object, java.lang.Object...) line: 727 
    org.junit.jupiter.engine.execution.MethodInvocation<T>.proceed() line: 60   
    org.junit.jupiter.engine.execution.InvocationInterceptorChain$ValidatingInvocation<T>.proceed() line: 131   
    io.helidon.microprofile.testing.junit5.HelidonJunitExtension(org.junit.jupiter.api.extension.InvocationInterceptor).interceptBeforeAllMethod(org.junit.jupiter.api.extension.InvocationInterceptor.Invocation<java.lang.Void>, org.junit.jupiter.api.extension.ReflectiveInvocationContext<java.lang.reflect.Method>, org.junit.jupiter.api.extension.ExtensionContext) line: 88    
    org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor$$Lambda.0x00007f1604305438.apply(org.junit.jupiter.api.extension.InvocationInterceptor, org.junit.jupiter.api.extension.InvocationInterceptor$Invocation, org.junit.jupiter.api.extension.ReflectiveInvocationContext, org.junit.jupiter.api.extension.ExtensionContext) line: not available   

And then @BeforeEach:

Thread [main] (Suspended (breakpoint at line 19 in io.helidon.microprofile.tests.testing.junit5.TestBefore))    
    io.helidon.microprofile.tests.testing.junit5.TestBefore.beforeEach() line: 19   
    java.lang.invoke.LambdaForm$DMH.0x00007f1604130800.invokeVirtual(java.lang.Object, java.lang.Object) line: not available    
    java.lang.invoke.LambdaForm$MH.0x00007f160431c400.invoke(java.lang.Object, java.lang.Object) line: not available    
    java.lang.invoke.Invokers$Holder.invokeExact_MT(java.lang.Object, java.lang.Object, java.lang.Object) line: not available   
    jdk.internal.reflect.DirectMethodHandleAccessor.invokeImpl(java.lang.Object, java.lang.Object[]) line: 153  
    jdk.internal.reflect.DirectMethodHandleAccessor.invoke(java.lang.Object, java.lang.Object[]) line: 103  
    java.lang.reflect.Method.invoke(java.lang.Object, java.lang.Object...) line: 580    
    org.jboss.weld.bean.proxy.ContextBeanInstance<T>(org.jboss.weld.bean.proxy.AbstractBeanInstance).invoke(java.lang.Object, java.lang.reflect.Method, java.lang.Object...) line: 38   
    org.jboss.weld.bean.proxy.ProxyMethodHandler.invoke(java.lang.Object, java.lang.reflect.Method, java.lang.reflect.Method, java.lang.Object[]) line: 106 
    io.helidon.microprofile.tests.testing.junit5.TestBefore$Proxy$_$$_WeldClientProxy.beforeEach() line: not available  
    java.lang.invoke.LambdaForm$DMH.0x00007f1604130800.invokeVirtual(java.lang.Object, java.lang.Object) line: not available    
    java.lang.invoke.LambdaForm$MH.0x00007f160431c400.invoke(java.lang.Object, java.lang.Object) line: not available    
    java.lang.invoke.Invokers$Holder.invokeExact_MT(java.lang.Object, java.lang.Object, java.lang.Object) line: not available   
    jdk.internal.reflect.DirectMethodHandleAccessor.invokeImpl(java.lang.Object, java.lang.Object[]) line: 153  
    jdk.internal.reflect.DirectMethodHandleAccessor.invoke(java.lang.Object, java.lang.Object[]) line: 103  
    java.lang.reflect.Method.invoke(java.lang.Object, java.lang.Object...) line: 580    
    org.junit.platform.commons.util.ReflectionUtils.invokeMethod(java.lang.reflect.Method, java.lang.Object, java.lang.Object...) line: 727 
sdyura commented 3 months ago

Helidon 4.0.10


java.lang.reflect.InaccessibleObjectException: Unable to make io.helidon.microprofile.testing.junit5.HelidonJunitExtension() accessible: module io.helidon.microprofile.testing.junit5 does not "opens io.helidon.microprofile.testing.junit5" to module org.junit.platform.commons

    at java.base/java.lang.reflect.AccessibleObject.throwInaccessibleObjectException(AccessibleObject.java:391)
    at java.base/java.lang.reflect.AccessibleObject.checkCanSetAccessible(AccessibleObject.java:367)
    at java.base/java.lang.reflect.AccessibleObject.checkCanSetAccessible(AccessibleObject.java:315)
    at java.base/java.lang.reflect.Constructor.checkCanSetAccessible(Constructor.java:194)
    at java.base/java.lang.reflect.Constructor.setAccessible(Constructor.java:187)
    at java.base/java.util.stream.ForEachOps$ForEachOp$OfRef.accept(ForEachOps.java:184)
    at java.base/java.util.Spliterators$ArraySpliterator.forEachRemaining(Spliterators.java:1024)
    at java.base/java.util.stream.ReferencePipeline$Head.forEach(ReferencePipeline.java:762)
    at java.base/java.util.stream.ReferencePipeline$7$1.accept(ReferencePipeline.java:276)
    at java.base/java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:197)
    at java.base/java.util.ArrayList$ArrayListSpliterator.forEachRemaining(ArrayList.java:1708)
    at java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:509)
    at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:499)
    at java.base/java.util.stream.ForEachOps$ForEachOp.evaluateSequential(ForEachOps.java:151)
    at java.base/java.util.stream.ForEachOps$ForEachOp$OfRef.evaluateSequential(ForEachOps.java:174)
    at java.base/java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
    at java.base/java.util.stream.ReferencePipeline.forEach(ReferencePipeline.java:596)
    at java.base/java.util.ArrayList.forEach(ArrayList.java:1596)

workaround, add:

--add-opens=io.helidon.microprofile.testing.junit5/io.helidon.microprofile.testing.junit5=org.junit.platform.commons
--add-opens=io.helidon.microprofile.testing.junit5/io.helidon.microprofile.testing.junit5=weld.core.impl
--add-opens=io.helidon.microprofile.testing.junit5/io.helidon.microprofile.testing.junit5=io.helidon.microprofile.cdi