java-ee-8weld-seweld-junit5

WeldSE with JUnit5 - Can't inject dependencies


This is my service class:

@Path("/foo")
@RequestScoped
public class FooService {

    @Inject @Log
    Logger logger;

    @GET
    @Produces(MediaType.TEXT_PLAIN)
    public String ping() {
        return "pong";
    }
}

In the same module I have an util class that provides the logger using a Log interface with @Qualifier annotation

public class WebResources {

    @Produces
    @RequestScoped
    public FacesContext produceFacesContext() {
        return FacesContext.getCurrentInstance();
    }


    @Produces @Log
    public Logger produceLog(InjectionPoint injectionPoint) {
        return Logger.getLogger(injectionPoint.getMember().getDeclaringClass().getName());
    }
}

Then I wrote a UnitTest using JUnit 5 + Weld SE

@EnableWeld
public class FooTest {

    @WeldSetup
    public WeldInitiator weld = WeldInitiator.from(FooService.class)
            .activate(RequestScoped.class)
            .build();


    @Test
    public void ping(FooService fooService) {

        fooService.ping();

    }

}

This produces the following error:

org.jboss.weld.exceptions.DeploymentException: WELD-001408: Unsatisfied dependencies for type Logger with qualifiers @Log
  at injection point [BackedAnnotatedField] @Inject @Log it.infocert.shop.rest.FooService.logger
  at it.infocert.shop.rest.FooService.logger(FooService.java:0)

How can I add the @Log dependency to Weld SE properly in a unit test?


Solution

  • The problem is that class WebResources isn't known to Weld once it starts the container for tests. The way it works is that you define what beans are in the container - you can add classes, packages and so on.

    In your case, it should be enough to change the WeldInitiator creation like this:

    @WeldSetup
    public WeldInitiator weld = WeldInitiator.from(FooService.class, WebResources.class)
            .activate(RequestScoped.class)
            .build();
    

    Note that there are various way how to start the WeldInitiator ranging from the simplest one such the one you use, all the way to providing your own fully configured org.jboss.weld.environment.se.Weld object.