JUnit testing fails for `session.save()` with error "Wanted but not invoked:" | Community
Skip to main content
Level 3
July 20, 2023
Solved

JUnit testing fails for `session.save()` with error "Wanted but not invoked:"

  • July 20, 2023
  • 4 replies
  • 1529 views

I am trying to create a unit test that checks whether `session.save();` has been called, in my service implementation below:

 

TagManagerServiceImpl.java

@8220494(service = TagManagerService.class, immediate = true) public class TagManagerServiceImpl implements TagManagerService { private static final Logger LOGGER = LoggerFactory.getLogger(TagManagerServiceImpl.class); @3214626 private ResourceResolverFactory resolverFactory; @3214626 private JcrTagManagerFactory jcrTagManagerFactory; public void createTag(String tagPath, String tagTitle, String tagDescription) { ResourceResolver resourceResolver = null; try { resourceResolver = ResolverUtil.newResolver(resolverFactory); Session session = resourceResolver.adaptTo(Session.class); TagManager tagManager = jcrTagManagerFactory.getTagManager(session); if (session != null) { tagManager.createTag(tagPath, tagTitle, tagDescription, true); session.save(); //<========== want to test this } } catch (Exception e) { LOGGER.error("Error while creating tag", e); } finally { if (resourceResolver != null && resourceResolver.isLive()) { resourceResolver.close(); } } } }

 

My JUnit test is as follow:

 

TagManagerServiceTest.java

@ExtendWith(MockitoExtension.class) public class TagManagerServiceTest { @InjectMocks private TagManagerServiceImpl tagManagerService; @Mock private ResourceResolverFactory resolverFactory; @Mock private JcrTagManagerFactory jcrTagManagerFactory; @Mock private Session session; @Mock private TagManager tagManager; @Mock private ResourceResolver resourceResolver; @BeforeEach public void setUp() { MockitoAnnotations.initMocks(this); try { when(ResolverUtil.newResolver(resolverFactory)).thenReturn(resourceResolver); when(resourceResolver.adaptTo(Session.class)).thenReturn(session); when(jcrTagManagerFactory.getTagManager(session)).thenReturn(tagManager); } catch (Exception e) { fail("Expected no exceptions, but got: " + e.getMessage()); } } @2785667 public void testCreateTag() { String tagPath = "some/tagPath"; String tagTitle = "TagTitle"; String tagDescription = "TagDescription"; tagManagerService.createTag(tagPath, tagTitle, tagDescription); try { verify(tagManager, times(1)).createTag(tagPath, tagTitle, tagDescription, true); System.out.println(mockingDetails(session).printInvocations()); // No interactions and stubbings found for mock: session verify(session, times(1)).save(); // <========= testing session.save(); } catch (Exception e) { fail("Expected no exceptions, but got: " + e.getMessage()); } } }

 

 

But when I run the test, I get the following error. The line 66 mentioned being `verify(session, times(1)).save();` in the above code.

Wanted but not invoked: session.save(); -> at com.mysite.core.services.TagManagerServiceTest.testCreateTag(TagManagerServiceTest.java:66) Actually, there were zero interactions with this mock.

 

As you can see in my test code, I troubleshot by placing `System.out.println(mockingDetails(session).printInvocations());` right before the test, and got the printed message "No interactions and stubbings found for mock: session".

 

How can I make sure that `session.save();` is property tested?

 

Thanks,

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

4 replies

aanchal-sikka
Community Advisor
Community Advisor
July 20, 2023

@sean12341 

 

I would suggest to use https://wcm.io/testing/ in the project. Its based on Sling and helps you test things more in AEM context than mocking it. So, the test cases of modifying/persisting things are more real.

 

With this set up, you can use assertFalse(session.hasPendingChanges()); to verify if the session.save() was called.

Aanchal Sikka
Nishant-Singh
Adobe Employee
Nishant-SinghAdobe EmployeeAccepted solution
Adobe Employee
July 20, 2023
joerghoh
Adobe Employee
Adobe Employee
July 20, 2023

I think your mocking is incorrect:

when(resourceResolver.adaptTo(Session.class)).thenReturn(session);

 

try this one:

when(resourceResolver.adaptTo(any(Session.class))).thenReturn(session);

 

yuriy_shestakov
Level 3
July 21, 2023

Not sure why it's not called, but I have some concerns that you have the old initialization of mocks

 

MockitoAnnotations.initMocks(this);

 

together with 

 

@ExtendWith(MockitoExtension.class)

 

 

Also, this one:

 

when(ResolverUtil.newResolver(resolverFactory)).thenReturn(resourceResolver);

 

looks like mocking of a static method, shouldn't it be 

 

try (MockedStatic<ResolverUtil> resolverUtil = Mockito.mockStatic(ResolverUtil.class)) { resolverUtil.when(() -> ResolverUtil.newResolver(resolverFactory))) .thenReturn(resourceResolver); // all the other code that uses ResolverUtil.newResolver() }

 

?

 

Are you sure your error "Error while creating tag" is not output in the maven output? Have you enabled simple logger or added the console output to your lidalia logger if you use it instead of the simple logger? I suppose there is NullPointerException actually on the line "resourceResolver.adaptTo..."