weld/weld-testing

How to inject @Context objects?

fstarred opened this issue · 4 comments

This is my unit test:


@MockitoSettings(strictness = Strictness.STRICT_STUBS)
@ExtendWith(MockitoExtension.class)
@DisplayName("configs resource")
@EnableWeld
public class ConfigTest {

    @Mock
    HttpServletRequest servletRequest;

   @WeldSetup
    public WeldInitiator weld = WeldInitiator
            .from(
                    MockCommonResources.class,
                    ConfigApiResource.class,
                    etc etc
            )
            .addBeans(createHttpServletRequest())
            .activate(
                    RequestScoped.class,
                    ApplicationScoped.class
            )
            .build();

    Bean<?> createHttpServletRequest() {
        return MockBean.builder()
                .types(HttpServletRequest.class)
                .create(o -> servletRequest)
                .build();
    }

    @Test
    @DisplayName("config")
    void config(ConfigResource configResource) {

        final String url = "areaclient.infocert.it";

        when(servletRequest.getHeader("Origin")).thenReturn(url);

        final DomainConfig output = configResource.get();
        assertNotNull(output);

    }
}

I can't inject HttpServletRequest because is a @context object.

Any hints?

I suppose you'd like to inject the bean created by createHttpServletRequest() to a non-CDI injection point, ie. @Context HttpServletRequest. If so you would have to add a mini CDI extension that would turn @Context HttpServletRequest into @Inject HttpServletRequest. AFAIK there is no API to perform this directly. But in fact, it shouldn't be that hard. You can consider using org.jboss.weld.environment.se.Weld.addContainerLifecycleObserver(ContainerLifecycleObserver<?>) and org.jboss.weld.environment.se.ContainerLifecycleObserver.processAnnotatedType() and javax.enterprise.inject.spi.ProcessAnnotatedType.configureAnnotatedType().

@mkouba sorry I tried but still have no idea how to use the methods you mention above with JUnit 5 framework :(

Something like that:

Weld weld = WeldInitiator.createWeld()
   .addContainerLifecycleObserver(ContainerLifecycleObserver.processAnnotatedType()
     .notify(pat -> pat.configureAnnotatedType()
       .filterMethods(m -> m.isAnnotationPresent(Context.class))
          .forEach(m -> m.add(javax.enterprise.inject.literal.InjectLiteral.INSTANCE))));

// and then...
WeldInitiator weld = WeldInitiator.from(weld)
            .addBeans(
                    MockCommonResources.class, ...);

Thank you very much!
I mention your help on stackoverflow