How to mock/unit test a Sling filter that does a redirect? (and other questions) | Community
Skip to main content
jayv25585659
Level 8
September 18, 2025
Solved

How to mock/unit test a Sling filter that does a redirect? (and other questions)

  • September 18, 2025
  • 2 replies
  • 383 views

2 questions

  1. How I check if the redirect happens in my unit test?
  2. I cannot get a proper mock of an OSGI service that provides me access to an OSGI config. When I try to debug my unit test and the execution enters the filter, provider is null. How can I code it so it's not null?

some code (unit test + filter class + service)

my unit test

@ExtendWith(AemContextExtension.class) class MaintenancePagePrincipalsFilterTest { private static final String MAINTENANCE_MODE_FLAG_TRUE = "true"; private static final String MAINTENANCE_PATH_PATH = "/content/myapp/sg/en/maintenance.html"; @Mock private HttpServletRequest request; @Mock private HttpServletResponse response; @Mock private FilterChain chain; private MaintenanceModeConfigurationProvider provider; private final AemContext context = new AemContext(); private MaintenancePageFilter filter; @BeforeEach void setUp() { MockitoAnnotations.openMocks(this); provider = mock(MaintenanceModeConfigurationProvider.class); context.registerService(MaintenanceModeConfigurationProvider.class, provider); filter = new MaintenancePageFilter(); } @2785667 void MaintenanceModeEnabled() throws IOException, ServletException { when(provider.getMaintenanceModeFlag()).thenReturn(MAINTENANCE_MODE_FLAG_TRUE); when(provider.getMaintenancePagePath()).thenReturn(MAINTENANCE_PATH_PATH); filter.doFilter(request, response, chain); verify(response).sendRedirect(MAINTENANCE_PATH_PATH); verify(chain, never()).doFilter(request, response); } }

filter class

public class MaintenancePageFilter implements Filter { @3214626 private MaintenanceModeConfigurationProvider provider; @9944223 public void init(FilterConfig filterConfig) throws ServletException { } @9944223 public void destroy() { } @9944223 public void doFilter(final ServletRequest request, final ServletResponse response, final FilterChain chain) throws IOException, ServletException { try { if (StringUtils.isNotBlank(provider.getMaintenanceModeFlag()) && StringUtils.isNotBlank(provider.getMaintenancePagePath()) { ((HttpServletResponse) response).sendRedirect( provider.getMaintenancePagePath()); return; } } catch (IOException exception) { } catch (IllegalStateException exception) { } chain.doFilter(request, response); } }

service class to access OSGI config

public class MaintenanceModeConfigurationProviderImpl implements MaintenanceModeConfigurationProvider { private MaintenanceModeConfiguration config; @580286 @9182423 protected void activate(MaintenanceModeConfiguration config) { this.config = config; } @9944223 public String getMaintenanceModeFlag() { return config.maintenanceModeFlag(); } @9944223 public String getMaintenancePagePath() { return config.maintenancePagePath(); } }

 

 

 

 

Best answer by HrishikeshKagne

Hi @jayv25585659 ,
Try this:

1. How to check redirect in your unit test

You already do the right thing:

verify(response).sendRedirect(MAINTENANCE_PATH_PATH); verify(chain, never()).doFilter(request, response);


That is exactly how you confirm the redirect happens.

2. Why provider is null in your filter

Your filter is written as an OSGi DS component but in the test you create it with new, so OSGi never injects @Reference -> provider stays null.


Make your filter an OSGi component (@Component(service = Filter.class) + @Reference MaintenanceModeConfigurationProvider provider).

In the test, don’t use new. Instead, register the mock in AemContext and let DS injection work:

@BeforeEach void setUp(AemContext context) { provider = mock(MaintenanceModeConfigurationProvider.class); context.registerService(MaintenanceModeConfigurationProvider.class, provider); // let AemContext create the filter with DS injection filter = context.registerInjectActivateService(new MaintenancePageFilter()); }


Now provider will not be null.

Keep verifying sendRedirect to test the redirect.

Don’t new your filter; use context.registerInjectActivateService so OSGi injection works and your provider is not null.

 

2 replies

HrishikeshKagne
Community Advisor
HrishikeshKagneCommunity AdvisorAccepted solution
Community Advisor
September 18, 2025

Hi @jayv25585659 ,
Try this:

1. How to check redirect in your unit test

You already do the right thing:

verify(response).sendRedirect(MAINTENANCE_PATH_PATH); verify(chain, never()).doFilter(request, response);


That is exactly how you confirm the redirect happens.

2. Why provider is null in your filter

Your filter is written as an OSGi DS component but in the test you create it with new, so OSGi never injects @Reference -> provider stays null.


Make your filter an OSGi component (@Component(service = Filter.class) + @Reference MaintenanceModeConfigurationProvider provider).

In the test, don’t use new. Instead, register the mock in AemContext and let DS injection work:

@BeforeEach void setUp(AemContext context) { provider = mock(MaintenanceModeConfigurationProvider.class); context.registerService(MaintenanceModeConfigurationProvider.class, provider); // let AemContext create the filter with DS injection filter = context.registerInjectActivateService(new MaintenancePageFilter()); }


Now provider will not be null.

Keep verifying sendRedirect to test the redirect.

Don’t new your filter; use context.registerInjectActivateService so OSGi injection works and your provider is not null.

 

Hrishikesh Kagane
September 18, 2025

Hi @jayv25585659  

 

Looking at your test class, the reason that provider object is null because the MaintenancePageFilter instance is not getting the mocked MaintenanceModeConfigurationProvider injected into it.

 

The issue is in your setup:

  1. You're registering the mock provider with the AemContext
  2. But you're creating the filter with new MaintenancePageFilter() instead of letting AemContext create and inject dependencies

As @hrishikeshkagne mentioned, registerInjectActivateService method ensures the mocked provider gets properly injected into the filter instance.

 

filter = context.registerInjectActivateService(new MaintenancePageFilter());

 

Based on my previous experience, this may not work, since AemContext can't handle the dependency injection automatically. You may need to manually inject the provider using reflection. So, instead of using, 

filter = context.registerInjectActivateService(new MaintenancePageFilter());


try the below code snippet.

 

filter = new MaintenancePageFilter(); // Manually inject the provider using reflection Field providerField = MaintenancePageFilter.class.getDeclaredField("provider"); providerField.setAccessible(true); providerField.set(filter, provider);