AEM Unit Test for servlet | Community
Skip to main content
December 13, 2021

AEM Unit Test for servlet

  • December 13, 2021
  • 4 replies
  • 6554 views

I have to write a Unit Test for a servlet that uses 

 

@Reference
private transient SearchService searchService;

When I run the doGetTest I get a NullPointerException since this searchService is null:


@Test
void doGetTest() throws IOException {

MockSlingHttpServletRequest request = context.request();
MockSlingHttpServletResponse response = context.response();
underTest.doGet(request, response);

How do I inject this SearchService in my Unit Test?

Thanks in advance.

This post is no longer active and is closed to new replies. Need help? Start a new post to ask your question.

4 replies

Kiran_Vedantam
Community Advisor
Community Advisor
December 13, 2021

Hi @anasustic 

 

Try to mock the service in your test class as mentioned here : https://taylor.callsen.me/unit-testing-aem-sling-models-and-servlets/

 

Hope this helps!

 

Thanks,

Kiran Vedantam.

milind_bachani
Adobe Employee
Adobe Employee
December 13, 2021

Hi @anasustic ,

You can use @Mock annotations for creating the mock instance of the service as:

@Mock
SearchService mockSearchService;

Then you can initialize your mocks using initMocks() in setUp() as:

@Before
public void setUp() throws Exception {
     MockitoAnnotations.initMocks(this);
}

And then inside test you can use :

servlet.searchService = mockSearchService;

Hope this helps, thanks!

anasusticAuthor
December 13, 2021

Thanks @milind_bachani but I do not unterstand how to do 

servlet.searchService = mockSearchService;

My servlet does not have a method searchService? 

December 13, 2021
import org.mockito.internal.util.reflection.Whitebox;

Whitebox.setInternalState(underTest, "searchservice", mockedSearchservice);
Vijayalakshmi_S
December 13, 2021

Hi @anasustic,

Use @Mock (org.mockito.Mock) annotation on the Service in  Test class and to inject this to the servlet under test, use @InjectMocks (org.mockito.InjectMocks) on the servlet instantiation like the below. 

 

@Mock
private SearchService searchService

@InjectMocks
private SimpleServlet underTest = new SimpleServlet();

Then in the doGetTest() method, before calling underTest.doGet(request, response) -> provide mock implementation for the searchService using when and thenReturn methods. 

Please update this thread in case of any issues. 

 

anasusticAuthor
December 13, 2021

I do not understand what do you mean by


mock implementation for the searchService using when and thenReturn methods. 

Please update this thread in case of any issues. 

 


This is what I have 

@ExtendWith(AemContextExtension.class)
class LocationFinderByTitleServiceTest {


private final AemContext context = ComponentTestContext.createAemContext();

@Mock
SearchService searchService;

@InjectMocks
private LocationFinderByTitleService underTest = new LocationFinderByTitleService();

@BeforeEach
void beforeEach() {
context.load().json("/component/content/location/content.json", "/content/de");


Map<String, Object> pm = new HashMap<>();
pm.put("title", "Shop");
context.request().setMethod("GET");
context.request().setParameterMap(pm);
}


@Test
void doGetTest() throws IOException {

MockSlingHttpServletRequest request = context.request();
MockSlingHttpServletResponse response = context.response();


underTest.doGet(request, response);

 I am getting a NullPointerException in the underTest.doGet while the searchService is null.

Vijayalakshmi_S
December 13, 2021

You might be using some method/functionality of SearchService in your actual Servlet class, you need to provide implementation for the same here to the test class. 

Example: If you have searchService.search() and that returns a List object say for example, then we need to write

when(searchService.search()).thenReturn(any(List.class));

 

Also, in the snippet you have shared, instantiate the AemContext like below 

private AemContext context = new AemContext(ResourceResolverType.RESOURCERESOLVER_MOCK);

or

private AemContext context = new AemContext(ResourceResolverType.JCR_MOCK);

 

BrianKasingli
Community Advisor and Adobe Champion
Community Advisor and Adobe Champion
December 13, 2021

Try this

 


...
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;

private SearchService searchService;

@Test
void doGetTest() throws IOException {
searchService = mock(SearchService.class);
when(searchService.get(any()).thenReturn(null);
MockSlingHttpServletRequest request = context.request();
MockSlingHttpServletResponse response = context.response();
underTest.doGet(request, response);

JsonObject jsonResponse = gson.fromJson(response.getOutputAsString(), JsonObject.class);
assertNotNull(jsonResponse.get("searchResults"));
}

 

anasusticAuthor
December 14, 2021

My SearchService class has two @3214626 annotations

 

@Reference
private ResourceResolverService resourceResolverService;

@Reference
private GeocodingService geocodingService;

and two public methods with the following signatures:

public List<LocationResult> getResults(@Nonnull GoogleMapsApiConfigurationModel configModel, @Nonnull String pagePath, @Nullable String zipCity)

 

public void cacheLocations(Resource resource)

 I am not sure how to mock that in 

when(searchService.getResults(???).thenReturn(???)