How to integrate CDI-Unit with Jersey Test Framework?

0

Hello.

I'm working on a ws rest with CDI and Jersey. I want to create a unit of tests with JUnit and due to the CDI I ended up using the CDI-Unit Runner. I found the CDI-Unit simpler than WeldJUnit4Runner.

Now, I need to add the Jersey Test Framework to test some features that will be consumed. But I'm not sure how to integrate the Jersey Test Framework into the CDI-Unit.

I have the following exception when running any test:

org.jboss.weld.exceptions.UnproxyableResolutionException: WELD-001437: 
Normal scoped bean class rest.resource.ContactResourceTest is not proxyable because the type is final or 
it contains a final method public final javax.ws.rs.client.
WebTarget org.glassfish.jersey.test.JerseyTest.target() - unknown javax.enterprise.inject.spi.Bean instance.
    at org.jboss.weld.util.Proxies.getUnproxyableClassException(Proxies.java:214)
    at org.jboss.weld.util.Proxies.getUnproxyableTypeException(Proxies.java:178)
    at org.jboss.weld.util.Proxies.getUnproxyableTypeException(Proxies.java:140)
    at org.jboss.weld.bean.proxy.ClientProxyProvider.getClientProxy(ClientProxyProvider.java:231)
    at org.jboss.weld.manager.BeanManagerImpl.getReference(BeanManagerImpl.java:736)
    at org.jboss.weld.bean.builtin.InstanceImpl.getBeanInstance(InstanceImpl.java:179)
    at org.jboss.weld.bean.builtin.InstanceImpl.get(InstanceImpl.java:99)
    at org.jglue.cdiunit.CdiRunner.createTest(CdiRunner.java:156)
    at org.jglue.cdiunit.CdiRunner.createTest(CdiRunner.java:138)
    at org.junit.runners.BlockJUnit4ClassRunner$1.runReflectiveCall(BlockJUnit4ClassRunner.java:266)
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
    at org.junit.runners.BlockJUnit4ClassRunner.methodBlock(BlockJUnit4ClassRunner.java:263)
    at org.jglue.cdiunit.CdiRunner.methodBlock(CdiRunner.java:164)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
    at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
    at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:68)
    at com.intellij.rt.execution.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:51)
    at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:237)
    at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:70)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at com.intellij.rt.execution.application.AppMain.main(AppMain.java:147)

Is it possible to integrate them? I can not find an example of these two guys working together. By the way, I need the CDI in the tests because some feature class has the @Inject annotation for services injection.

@RunWith(CdiRunner.class)
@AdditionalClasses({LoggerProducerUtil.class})
@ActivatedAlternatives(JPATest.class)
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
public class ContactResourceTest extends JerseyTest {

    @Inject
    private AuthenticationService service;
    private Client client;

    @Override
    protected Application configure() {
        return new ResourceConfig(
                ContactResource.class);
    }

    // @Test omitidos   
}
    
asked by anonymous 27.05.2017 / 08:12

1 answer

0

I could not solve the problem with CDI-Unit, but I was able to run the tests I wanted in the following way. I extended the Jersey into the test class and then had to set up an AbstractBuilder to do the Bind among the injectable beans that are part of the features that would be tested.

public class CustomerResourceTest extends JerseyTest {

    @Override
    protected Application configure() {
        return new ResourceConfig()
                .packages(true, "br.com.devmedia.crudrest.resource")
                .register(new AbstractBinder() {
                    @Override
                    protected void configure() {
                        bind(CustomerServiceImpl.class).to(CustomerService.class);
                        bindFactory(EntityManagerFactoryTest.class).to(EntityManagerFactory.class);
                        bindFactory(EntityManagerTest.class).to(EntityManager.class);
                    }
                });
    } 

    // testes aqui  
}

Now the EntityManagerFactoryTest and EntityManagerTest classes I created inside the test unit itself, so that my entityManager in the application was injected into Dao's.

public class EntityManagerFactoryTest implements Factory<EntityManagerFactory> {

    private final EntityManagerFactory factory;

    public EntityManagerFactoryTest() {
        factory = Persistence.createEntityManagerFactory("JPAUtilTest");
    }

    @Override
    public void dispose(EntityManagerFactory factory) {
        factory.close();
    }

    @Override
    public EntityManagerFactory provide() {
        return factory;
    }
}

public class EntityManagerTest implements Factory<EntityManager> {

    private final EntityManagerFactory factory;
    private final CloseableService closeService;

    @Inject
    public EntityManagerTest(EntityManagerFactory factory, CloseableService closeService) {
        this.factory = factory;
        this.closeService = closeService;
    }

    @Override
    public void dispose(EntityManager entityManager) {
        if (entityManager != null && entityManager.isOpen()) {
            entityManager.close();
        }
    }

    @Override
    public EntityManager provide() {
        final EntityManager entityManager = factory.createEntityManager();
        this.closeService.add(new Closeable(){
            @Override
            public void close() {
                entityManager.close();
            }
        });
        return entityManager;
    }
}

In this way I was able to perform the tests using CDI to inject the service into the Jersey resource.

    
04.06.2017 / 20:04