Search code examples
unit-testingcdijunit5weld

unit tests which need CDI container result in java.lang.IllegalStateException: Unable to access CDI


I'm using Weld for CDI.

I'm trying to write a unit test for service "A" using JUnit 5. The constructor of service A is:

@Inject
public A (B b) {this.b = b}

Class B constructor is:

@ApplicationScoped
public class B{ 

private C c;
    public B() {
        c = CDI.current().select(C.class).get();
    }
}

When i try to mock Class B during unit tests i get:

java.lang.IllegalStateException: Unable to access CDI

because during unit tests there isn't a proper CDI container.

How can resolve this issue? is there anyway to it with Mockito? (let's assume that replacing the CDI.current() is not an option)

This how the test code looks:

public class ATest {
private A a;

@WeldSetup
    private WeldInitiator weld = WeldInitiator.from(A.class)
        .addBeans(createBBean()).build();

    private Bean<?> createBBean() {
        return MockBean.builder()
            .types(B.class)
            .scope(ApplicationScoped.class)
            .creating(new B())
            .build();
    }

    @BeforeEach
    void setUpClass() {
        a = weld.select(A.class).get();
     }
}

Solution

  • I always do this (CDI 2.0 and later):

    private SeContainer container;
    
    @BeforeEach
    private void startContainer() {
      SeContainerInitializer initializer = SeContainerInitializer.newInstance();
      // add what you want, disable discovery, whatever
      this.container = initializer.initialize();
    }
    
    @AfterEach
    private void stopContainer() {
      if (this.container != null) {
        this.container.close();
      }
    }
    

    Then any @Test has access to CDI.