Hi everyone ,
I am facing issue in mocking a sling model object which have custom annotation.
this is my model class for which i am writing test class : -
Solved! Go to Solution.
Views
Replies
Total Likes
Hi @varunkiroriwal ,
To properly mock the Optional<SiteSlingModel> and ensure it's injected into your DownloadLinkModel, you need to ensure the custom injector is correctly set up and registered in the AEM context. The approach involves a few key steps: ensuring the injector is recognized, registering your mocks appropriately, and verifying the custom annotation behaves as expected.
Here's a more detailed and structured approach:
Ensure your custom injector implementation is correctly defined and registers the SiteSlingModel appropriately. If MySiteConfigInjectorImpl isn't handling the injection properly, SiteSlingModel won't be injected.
Make sure that your DownloadLinkModel and any other necessary models are correctly registered in the AEM context.
Ensure that the mock for SiteSlingModel is registered correctly and that the custom injector is appropriately used.
Here’s a complete example:
Ensure your injector correctly injects the SiteSlingModel based on your custom annotation.
public class MySiteConfigInjectorImpl implements Injector {
public static final String MY_SITE_CONFIG_INJECT = "mysiteconfiginject";
@Override
public String getName() {
return MY_SITE_CONFIG_INJECT;
}
@Override
public Object getValue(Object adaptable, String name, Type type, AnnotatedElement element, DisposalCallbackRegistry callbackRegistry) {
if (type instanceof ParameterizedType) {
ParameterizedType parameterizedType = (ParameterizedType) type;
if (parameterizedType.getRawType().equals(Optional.class) &&
parameterizedType.getActualTypeArguments()[0].equals(SiteSlingModel.class)) {
// Custom logic to provide the SiteSlingModel instance
return Optional.of(new SiteSlingModel()); // Replace with actual logic
}
}
return null;
}
}
Here's your test class with some adjustments:
@ExtendWith(AemContextExtension.class)
class DownloadLinkModelTest {
private static final String TEST_PATH = "/content/en/page/jcr:content/root/responsivegrid";
public final AemContext context = new AemContext();
private DownloadLinkModel downloadLinkModel;
@Mock
private Resource resource;
@Mock
private SiteSlingModel siteSlingModel;
@Spy
private MySiteConfigInjectorImpl mySiteConfigInjector;
@BeforeEach
public void setup() {
MockitoAnnotations.initMocks(this);
context.addModelsForClasses(DownloadLinkModel.class);
context.create().page("/content/en");
Page page = context.create().page("/content/en/page");
context.currentPage(page);
context.load().json("downloadlink.json", "/resource");
resource = context.currentResource("/resource/downloadlink-tags");
context.request().setResource(resource);
// Register the custom injector
context.registerService(Injector.class, mySiteConfigInjector);
// Register the adapter
context.registerAdapter(SlingHttpServletRequest.class, SiteSlingModel.class, siteSlingModel);
// Mock the SiteSlingModel method
when(siteSlingModel.getDateFormat()).thenReturn("true");
// Adapt the request to the model
downloadLinkModel = context.request().adaptTo(DownloadLinkModel.class);
}
@Test
@DisplayName("Test getDownloadLink - Tags List")
public void testGetDownloadLinkTagsList() {
assertNotNull(downloadLinkModel);
assertEquals("tags", downloadLinkModel.getListType());
assertEquals("title", downloadLinkModel.getSortBy());
}
}
Register the Custom Injector: Ensure that your custom injector is registered in the AEM context (context.registerService(Injector.class, mySiteConfigInjector);).
Mock the SiteSlingModel: Create the mock for SiteSlingModel and set up its behavior (when(siteSlingModel.getDateFormat()).thenReturn("true");).
Adapt the Request to the Model: Ensure the request is adapted to the DownloadLinkModel after setting up all mocks and services.
Custom Annotation Handling: Make sure the custom annotation is properly recognized and handled by your custom injector.
By following these steps, you should be able to properly mock and inject the Optional<SiteSlingModel> into your DownloadLinkModel and avoid the NullPointerException.
Hi @varunkiroriwal ,
To mock an instance of Optional<SiteSlingModel> which is annotated with a custom annotation, you can use the @Mock annotation from Mockito and create a mock object for SiteSlingModel. Here's an example of how you can modify your test class to mock the siteSlingModel:
@ExtendWith(value = {AemContextExtension.class})
class DownloadLinkModelTest {
private static final String TEST_PATH = "/content/en/page/jcr:content/root/responsivegrid";
public final AemContext context = new AemContext();
private DownloadLinkModel downloadLinkModel;
@Mock
private Resource resource;
@Mock
private SiteSlingModel siteSlingModel;
@BeforeEach
public void setup() {
MockitoAnnotations.initMocks(this);
context.addModelsForClasses(DownloadLinkModel.class);
context.create().page("/content/en");
Page page = context.create().page("/content/en/page");
context.currentPage(page);
context.load().json("downloadlink.json", "/resource");
resource = context.currentResource("/resource/downloadlink-tags");
context.request().setResource(resource);
// Mock the siteSlingModel
when(siteSlingModel.getDateFormat()).thenReturn("true");
downloadLinkModel = context.request().adaptTo(DownloadLinkModel.class);
}
@Test
@DisplayName("Test getDownloadLink - Tags List")
public void testGetDownloadLinkTagsList() {
assertNotNull(downloadLinkModel);
assertEquals("tags", downloadLinkModel.getListType());
assertEquals("title", downloadLinkModel.getSortBy());
}
}
In the setup() method, after initializing the mocks with MockitoAnnotations.initMocks(this), you can use when(siteSlingModel.getDateFormat()).thenReturn("true") to mock the behavior of the getDateFormat() method of SiteSlingModel and return the desired value.
Make sure that the SiteSlingModel mock is properly injected into the DownloadLinkModel during the test setup. This should resolve the NullPointerException you were encountering when accessing siteSlingModel.isPresent().
Note: If the @MySiteConfigInjector annotation has additional behavior or dependencies, you may need to mock those as well to ensure the proper functioning of the test.
Views
Replies
Total Likes
Hi @HrishikeshKa
thanks for the response.
i tried as you said but still getting null pointer exception in same line.
declared custom annotation source class:-
I added these lines into my setup method:-
This is the Custom Annotation class:-
Still SiteSlingModel mock is not getting injected properly into the DownloadLinkModel.
Views
Replies
Total Likes
Hi @varunkiroriwal ,
To properly mock the Optional<SiteSlingModel> and ensure it's injected into your DownloadLinkModel, you need to ensure the custom injector is correctly set up and registered in the AEM context. The approach involves a few key steps: ensuring the injector is recognized, registering your mocks appropriately, and verifying the custom annotation behaves as expected.
Here's a more detailed and structured approach:
Ensure your custom injector implementation is correctly defined and registers the SiteSlingModel appropriately. If MySiteConfigInjectorImpl isn't handling the injection properly, SiteSlingModel won't be injected.
Make sure that your DownloadLinkModel and any other necessary models are correctly registered in the AEM context.
Ensure that the mock for SiteSlingModel is registered correctly and that the custom injector is appropriately used.
Here’s a complete example:
Ensure your injector correctly injects the SiteSlingModel based on your custom annotation.
public class MySiteConfigInjectorImpl implements Injector {
public static final String MY_SITE_CONFIG_INJECT = "mysiteconfiginject";
@Override
public String getName() {
return MY_SITE_CONFIG_INJECT;
}
@Override
public Object getValue(Object adaptable, String name, Type type, AnnotatedElement element, DisposalCallbackRegistry callbackRegistry) {
if (type instanceof ParameterizedType) {
ParameterizedType parameterizedType = (ParameterizedType) type;
if (parameterizedType.getRawType().equals(Optional.class) &&
parameterizedType.getActualTypeArguments()[0].equals(SiteSlingModel.class)) {
// Custom logic to provide the SiteSlingModel instance
return Optional.of(new SiteSlingModel()); // Replace with actual logic
}
}
return null;
}
}
Here's your test class with some adjustments:
@ExtendWith(AemContextExtension.class)
class DownloadLinkModelTest {
private static final String TEST_PATH = "/content/en/page/jcr:content/root/responsivegrid";
public final AemContext context = new AemContext();
private DownloadLinkModel downloadLinkModel;
@Mock
private Resource resource;
@Mock
private SiteSlingModel siteSlingModel;
@Spy
private MySiteConfigInjectorImpl mySiteConfigInjector;
@BeforeEach
public void setup() {
MockitoAnnotations.initMocks(this);
context.addModelsForClasses(DownloadLinkModel.class);
context.create().page("/content/en");
Page page = context.create().page("/content/en/page");
context.currentPage(page);
context.load().json("downloadlink.json", "/resource");
resource = context.currentResource("/resource/downloadlink-tags");
context.request().setResource(resource);
// Register the custom injector
context.registerService(Injector.class, mySiteConfigInjector);
// Register the adapter
context.registerAdapter(SlingHttpServletRequest.class, SiteSlingModel.class, siteSlingModel);
// Mock the SiteSlingModel method
when(siteSlingModel.getDateFormat()).thenReturn("true");
// Adapt the request to the model
downloadLinkModel = context.request().adaptTo(DownloadLinkModel.class);
}
@Test
@DisplayName("Test getDownloadLink - Tags List")
public void testGetDownloadLinkTagsList() {
assertNotNull(downloadLinkModel);
assertEquals("tags", downloadLinkModel.getListType());
assertEquals("title", downloadLinkModel.getSortBy());
}
}
Register the Custom Injector: Ensure that your custom injector is registered in the AEM context (context.registerService(Injector.class, mySiteConfigInjector);).
Mock the SiteSlingModel: Create the mock for SiteSlingModel and set up its behavior (when(siteSlingModel.getDateFormat()).thenReturn("true");).
Adapt the Request to the Model: Ensure the request is adapted to the DownloadLinkModel after setting up all mocks and services.
Custom Annotation Handling: Make sure the custom annotation is properly recognized and handled by your custom injector.
By following these steps, you should be able to properly mock and inject the Optional<SiteSlingModel> into your DownloadLinkModel and avoid the NullPointerException.
@varunkiroriwal Did you find the suggestion helpful? Please let us know if you require more information. Otherwise, please mark the answer as correct for posterity. If you've discovered a solution yourself, we would appreciate it if you could share it with the community. Thank you!
Views
Replies
Total Likes