Search code examples
mockitojunit5-extension-modelweld-junit5

junit5 + weld + mockito extension, how to inject @Context object


This is my REST resource:

@Context
HttpServletRequest webRequest;


@Override
public DomainConfig get() {
    return configDelegate.get(webRequest.getHeader("Origin"));
}

I've built my unit test with Junit 5 + Weld / Mockito extension.

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

    @Mock
    HttpServletRequest servletRequest;

    @WeldSetup
    public WeldInitiator weld = WeldInitiator
            .from(
                    MockCommonResources.class,
                    ConfigApiResource.class,
                    ConfigDelegate.class,
                    ConfigService.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(ConfigApiResource configApiResource) {

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

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

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

    }
}

The issue is HttpServletRequest webRequest is always null, probably because is not injected but it is a context object.

So the real question is, how can I produce a HttpServletRequest mock and inject as a @Context object?


Solution

  • After asking help also to weld-junit group, user mkouba gave the final solution.

    final Weld weldBase = WeldInitiator.createWeld()
                .addBeanClasses(
                        MockCommonResources.class,
                        ConfigApiResource.class,
                        ConfigDelegate.class,
                        ConfigService.class,
                        etc etc
                )
                .addContainerLifecycleObserver(ContainerLifecycleObserver.processAnnotatedType()
                        .notify(pat -> pat.configureAnnotatedType()
                                .filterFields(m -> m.isAnnotationPresent(Context.class))
                                .forEach(m -> m.add(javax.enterprise.inject.literal.InjectLiteral.INSTANCE))));
    
    
        @WeldSetup
        public WeldInitiator weld = WeldInitiator
                .from(
                        weldBase
                )
                .activate(
                        RequestScoped.class,
                        ApplicationScoped.class
                )
                .addBeans(createHttpServletRequest())
                .build();
    

    By adding the observer on Context annotation, the servletRequest mock is properly injected on ConfigApiResource