0

Java 8

Maven 3.9,7

I want to validate that a private method was called once.

In my pom.xml:

<dependency> <groupId>org.mockito</groupId> <artifactId>mockito-core</artifactId> <version>3.12.4</version> <scope>test</scope> </dependency> <dependency> <groupId>org.mockito</groupId> <artifactId>mockito-inline</artifactId> <version>3.12.4</version> <scope>test</scope> </dependency> <dependency> <groupId>org.powermock</groupId> <artifactId>powermock-module-junit4</artifactId> <version>2.0.2</version> <scope>test</scope> </dependency> <dependency> <groupId>org.powermock</groupId> <artifactId>powermock-api-mockito2</artifactId> <version>2.0.2</version> <scope>test</scope> </dependency> 

Here's my class:

public class MyClass { @Override public void handle(AttendantRequestEvent event) { String eventId = UUID.randomUUID().toString(); myPrivateMethod(eventId, eventId); } private void myPrivateMethod(String eventId, String eventId2) { System.out.println("myPrivateMethod, eventId = " + eventId + ", eventId2 = " + eventId2); } } 

Here's the unit test:

import static org.assertj.core.api.Assertions.assertThat; import static org.junit.Assert.assertNotNull; import static org.mockito.Answers.RETURNS_DEEP_STUBS; import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.*; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.*; import org.powermock.api.mockito.PowerMockito; import org.powermock.core.classloader.annotations.PrepareForTest; import org.powermock.modules.junit4.PowerMockRunner; @RunWith(PowerMockRunner.class) @PrepareForTest(MyClass.class) public class MyClassTest { @Test public void shouldCallMyPrivateMethod() throws Exception { try (MockedStatic<UUID> utilities = Mockito.mockStatic(UUID.class)) { AssistanceRequestsHandler assistanceRequestsHandlerMock = PowerMockito.spy(new AssistanceRequestsHandler()); String fixedUuid = "a1b2c3d4-e5f6-7890-1234-567890abcdef"; UUID uuidMock = mock(UUID.class); utilities.when(UUID::randomUUID).thenReturn(uuidMock); when(uuidMock.toString()).thenReturn(fixedUuid); // Act assistanceRequestsHandlerMock.handle(new InfoEvent(any())); // Assert PowerMockito.verifyPrivate(assistanceRequestsHandlerMock, times(1)) .invoke("myPrivateMethod", fixedUuid, fixedUuid); } } } 

And it's working just fine. Here's a result:

myPrivateMethod, eventId = a1b2c3d4-e5f6-7890-1234-567890abcdef, eventId2 = a1b2c3d4-e5f6-7890-1234-567890abcdef 

Nice.

Now, I want to use a logger in my private method, e.g. something like this (in MyClass.java):

private void myPrivateMethod(String eventId, String eventId2) { Logger.info(this, "myPrivateMethod, eventId_1 = {}, eventId_2 {}", eventId, eventId2); } 

And the test was successfully passed, but it raised the next error:

ScriptEngineManager providers.next(): javax.script.ScriptEngineFactory: Provider jdk.nashorn.api.scripting.NashornScriptEngineFactory not a subtype 2025-04-25 12:12:15,086 main ERROR Could not reconfigure JMX java.lang.LinkageError: loader constraint violation: loader (instance of org/powermock/core/classloader/javassist/JavassistMockClassLoader) previously initiated loading for a different type with name "javax/management/MBeanServer" at java.lang.ClassLoader.defineClass1(Native Method) at java.lang.ClassLoader.defineClass(ClassLoader.java:757) at org.powermock.core.classloader.javassist.JavassistMockClassLoader.loadUnmockedClass(JavassistMockClassLoader.java:90) at org.powermock.core.classloader.MockClassLoader.loadClassByThisClassLoader(MockClassLoader.java:104) at org.powermock.core.classloader.DeferSupportingClassLoader.loadClass1(DeferSupportingClassLoader.java:147) at org.powermock.core.classloader.DeferSupportingClassLoader.loadClass(DeferSupportingClassLoader.java:98) at java.lang.ClassLoader.loadClass(ClassLoader.java:352) at org.apache.logging.log4j.core.jmx.Server.unregisterAllMatching(Server.java:337) 
2
  • 1
    Likely not your problem, but assistanceRequestsHandlerMock.handle(new InfoEvent(any())); is nonsense. any() must only be used when stubbing or verifying methods. It cannot be used as arguments to other methods and will corrupt Mockito's Matcher stack. That and it simply returns null, so the call is effectively new InfoEvent(null) (plus, as written: confusing Mockito by having unused matchers on its stack). I'm really not sure if stubbing the static UUID.randomUUID() function is a good idea. And if I remember corectly, you cannot stub toString(), but I might be mistaken here Commented Apr 25 at 20:52
  • 1
    Following up on "mocking UUID": you are not basically testing anything. If you change your verification to verifyPrivate("myPrivateMethod", anyString(), anyString)), it would be equally "good". If you use two argument captors, you could even assert that both arguments are the same/equal. Commented Apr 25 at 20:55

0

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.