Hi Everybody.
I opened a previous ticket : https://experienceleaguecommunities.adobe.com/t5/adobe-experience-manager/mocking-jobmanager-in-juni... because i had issue on mocking annotations.
I am opening a new ticket ( related to the previous ) because i will appreciate help or explanations that let me understand the process.
I have a service : scheduleJob.
In that service i have a function scheduling a job. It will looks like :
class ScheduleJob...
public void startMyJob(String topic, Map<String, Object> jobProperties) {
JobBuilder jobBuilder =jobManager.createJob(topic);
jobBuilder.properties(jobProperties); Line XXX
JobBuilder.ScheduleBuilder scheduleBuilder =jobBuilder.schedule();
scheduleBuilder.cron(schedulerExpression);
List<String> errors = new ArrayList<>();
ScheduledJobInfo scheduledJobInfo=scheduleBuilder.add(errors);
if(scheduledJobInfo==null){
do Something
}
}
else{
do something else
}
}
and in my unit test i have something like that :
class scheduleJobTest {
@Mock
private JobManager jobManager;
@Mock
private JobBuilder jobBuilder;
@Mock
private JobBuilder.ScheduleBuilder scheduleBuilder;
@InjectMocks
private ScheduleJob scheduleJob = new ScheduleJob() ;
AemContext aemContext = new AemContext();
@BeforeEach
void setUp() {
aemContext.registerService(JobManager.class,jobManager);
aemContext.registerService(JobBuilder.class,jobBuilder);
aemContext.registerService(JobBuilder.ScheduleBuilder.class,scheduleBuilder);
aemContext.registerInjectActivateService(ScheduleJob);
}
@Test
startMyJob(){
scheduleJob.startMyJob(); Line XXY
assert...
}
And it gives me a null pointer exception at line XXY inside the function scheduleJob.startMyJob at Line XXX.
Maybe i am not understanding how it works and i am not using the right method to do it. But the idea is :
I mock the JobManager, JobBuilder and all the ref/services needed in my scheduleJob Class and then i can just call my function and test it in UnitTestClass. Or do i need to stub them ? If i do that, where is the point to call my function ?
If someone could help me it will be really nice
Thanks in advance,
Regards
Solved! Go to Solution.
Views
Replies
Total Likes
Hi @Dody ,
Since you are mocking JobManager and not actually initializing it, you will not get actual working on the service and hence every operation that you do with JobManager has to be handled by you in test class accordingly.
Refer this example:
@Mock
private ResourceResolver resolver;
@Mock
private ResourceResolverFactory factory;
@InjectMocks
private MyService myService;
now if someMethod() in myService is calling factory.getServiceResourceResolver() method you have to tell your test method want has to be returned from this call.
This can be done as shown below:
lenient().when(factory.getServiceResourceResolver(anyMap())).thenReturn(resolver);
Please be noted that you can return a mocking object or any value of your choice. In my case I am returning a mock resourceResolver.
In your case it should be, add below line before Line XXY
lenient().when(jobManager.createJob(any()).thenReturn(jobBuilder); (same applies for jobBuilder again)
Refer to this link https://experienceleague.adobe.com/docs/experience-manager-learn/getting-started-wknd-tutorial-devel...
Thanks!
Hi @Dody ,
Since you are mocking JobManager and not actually initializing it, you will not get actual working on the service and hence every operation that you do with JobManager has to be handled by you in test class accordingly.
Refer this example:
@Mock
private ResourceResolver resolver;
@Mock
private ResourceResolverFactory factory;
@InjectMocks
private MyService myService;
now if someMethod() in myService is calling factory.getServiceResourceResolver() method you have to tell your test method want has to be returned from this call.
This can be done as shown below:
lenient().when(factory.getServiceResourceResolver(anyMap())).thenReturn(resolver);
Please be noted that you can return a mocking object or any value of your choice. In my case I am returning a mock resourceResolver.
In your case it should be, add below line before Line XXY
lenient().when(jobManager.createJob(any()).thenReturn(jobBuilder); (same applies for jobBuilder again)
Refer to this link https://experienceleague.adobe.com/docs/experience-manager-learn/getting-started-wknd-tutorial-devel...
Thanks!
Hello @MohitKumarK ,
Thanks for the answer. It's more clear now.
I did that and then the tests passes.
So if i understood well, in my test method i am only calling my serviceMethod.
@Test
startMyJob(){
scheduleJob.startMyJob();
Then if i correctly set up the right "when..thenReturn" instructions, i had nothing to do more ? No need to assertTrue.../equals.. nothing ?
Thanks in advance
Regards
Hi @Dody ,
You still need to do assertions based on your class that you intended to test. That is the main purpose of writing a test case. In your case you are writing a junit class for a service so you can assert outcome of methods inside it.
Please mark correct answer such that wider people can refer this question.
Thanks!
Hi @MohitKumarK ,
But here is my question, because my service method is only creating a scheduled job and nothing is returned.
So i mocked everything, it's fine but i don't now what to assert.
Thanks for your help. I put it as correct answer.
Views
Likes
Replies