Reputation: 381
I am trying to mock static classes(org.apache.commons.beanutils.Beanutils) for Junit 5 test cases. I came across mockito-inline
dependency helps with mocking static classes.
I tried to use the mockito-inline
in the project for some strange reason it give me compilation error in the absence of mockito-core
library.
With mockito-core
am getting below:
org.mockito.exceptions.base.MockitoException:
The used MockMaker PowerMockMaker does not support the creation of static mocks
Mockito's inline mock maker supports static mocks based on the Instrumentation API.
You can simply enable this mock mode, by placing the 'mockito-inline' artifact where you are currently using 'mockito-core'.
Note that Mockito's inline mock maker is not supported on Android.
at com.xx.xx.xx.AvroCopyPropertiesInvocationTargetExceptionScenario(CreditOfferServiceTest.java:1197)
at org.junit.platform.commons.util.ReflectionUtils.invokeMethod(ReflectionUtils.java:675)
at org.junit.jupiter.engine.execution.MethodInvocation.proceed(MethodInvocation.java:60)
at org.junit.jupiter.engine.execution.InvocationInterceptorChain$ValidatingInvocation.proceed(InvocationInterceptorChain.java:125)
at org.junit.jupiter.engine.extension.TimeoutExtension.intercept(TimeoutExtension.java:132)
at org.junit.jupiter.engine.extension.TimeoutExtension.interceptTestableMethod(TimeoutExtension.java:124)
at org.junit.jupiter.engine.extension.TimeoutExtension.interceptTestMethod(TimeoutExtension.java:74)
at org.junit.jupiter.engine.execution.ExecutableInvoker$ReflectiveInterceptorCall.lambda$ofVoidMethod$0(ExecutableInvoker.java:115)
at org.junit.jupiter.engine.execution.ExecutableInvoker.lambda$invoke$0(ExecutableInvoker.java:105)
at org.junit.jupiter.engine.execution.InvocationInterceptorChain$InterceptedInvocation.proceed(InvocationInterceptorChain.java:104)
at org.junit.jupiter.engine.execution.InvocationInterceptorChain.proceed(InvocationInterceptorChain.java:62)
at org.junit.jupiter.engine.execution.InvocationInterceptorChain.chainAndInvoke(InvocationInterceptorChain.java:43)
at org.junit.jupiter.engine.execution.InvocationInterceptorChain.invoke(InvocationInterceptorChain.java:35)
at org.junit.jupiter.engine.execution.ExecutableInvoker.invoke(ExecutableInvoker.java:104)
at org.junit.jupiter.engine.execution.ExecutableInvoker.invoke(ExecutableInvoker.java:98)
at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.lambda$invokeTestMethod$6(TestMethodTestDescriptor.java:202)
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.invokeTestMethod(TestMethodTestDescriptor.java:198)
at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:135)
at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:69)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$5(NodeTestTask.java:135)
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$7(NodeTestTask.java:125)
at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:135)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:123)
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:122)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:80)
at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:38)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$5(NodeTestTask.java:139)
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$7(NodeTestTask.java:125)
at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:135)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:123)
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:122)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:80)
at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:38)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$5(NodeTestTask.java:139)
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$7(NodeTestTask.java:125)
at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:135)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:123)
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:122)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:80)
at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.submit(SameThreadHierarchicalTestExecutorService.java:32)
at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor.execute(HierarchicalTestExecutor.java:57)
at org.junit.platform.engine.support.hierarchical.HierarchicalTestEngine.execute(HierarchicalTestEngine.java:51)
at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:229)
at org.junit.platform.launcher.core.DefaultLauncher.lambda$execute$6(DefaultLauncher.java:197)
at org.junit.platform.launcher.core.DefaultLauncher.withInterceptedStreams(DefaultLauncher.java:211)
at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:191)
at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:137)
at org.eclipse.jdt.internal.junit5.runner.JUnit5TestReference.run(JUnit5TestReference.java:98)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:41)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:542)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:770)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:464)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:210)
Without the core - compilation issue. Please find the test dependency breakdown without mockito-core
:
[INFO] +- org.powermock:powermock-api-mockito2:jar:2.0.9:test
[INFO] | \- org.powermock:powermock-api-support:jar:2.0.9:test
[INFO] | +- org.powermock:powermock-reflect:jar:2.0.9:test
[INFO] | \- org.powermock:powermock-core:jar:2.0.9:test
[INFO] +- org.mockito:mockito-inline:jar:3.6.28:test
[INFO] | \- org.mockito:mockito-core:jar:3.1.0:test
[INFO] | +- net.bytebuddy:byte-buddy:jar:1.10.10:test
[INFO] | +- net.bytebuddy:byte-buddy-agent:jar:1.10.10:test
[INFO] | \- org.objenesis:objenesis:jar:2.6:test
[INFO] +- org.mockito:mockito-junit-jupiter:jar:3.6.0:test
[INFO] | \- org.junit.jupiter:junit-jupiter-api:jar:5.5.2:test
[INFO] | +- org.opentest4j:opentest4j:jar:1.2.0:test
[INFO] | \- org.junit.platform:junit-platform-commons:jar:1.5.2
Upvotes: 37
Views: 111638
Reputation: 53
I have faced this issue while trying to use Mockito5 with JDK8, the thing is that "Instrumentation API" is not supported by JDK8(this is what allows you to mock static classes on runtime) , which is included in JDK9 and later.
Instrumentation API allows you to alter existing byte-code that is loaded in a JVM.
Solution 1 : Here is the work around I did to overcome this issue :
dependencies{
....
testImplementation group: 'org.mockito', name: 'mockito-inline', version: '4.8.0'
implementation group: 'net.bytebuddy', name: 'byte-buddy-agent', version: '1.12.14'
}
configurations {
byteBuddyAgent
compile.extendsFrom byteBuddyAgent
}
test {
// Add the Byte Buddy agent to the JVM arguments during testing, which will be retrieved by the inline-mockito during runtime.
doFirst {
// Get the list of dependencies.
List<File> dependencies = configurations.compileClasspath.files.toList()
// Find the jar file for the `byte-buddy-agent` dependency.
File byteBuddyAgent = dependencies.find { file -> file.path.contains('byte-buddy-agent') }
if (byteBuddyAgent != null) {
// Get the path to the jar file.
jarPath = byteBuddyAgent.absolutePath
jvmArgs '-javaagent:' + jarPath
} else {
// Handle the case when the desired JAR file is not found.
println "The 'byte-buddy-agent' jar file was not found in the dependencies."
}
}
finalizedBy jacocoTestReport // report is always generated after tests run
}
Solution 2 : Using PowerMockito wans't practicle for me beacause I need to run jacococ reports to see the code coverage and jacoco doesn't like PowerMockito for some reason.
Upvotes: 1
Reputation: 71
I have some resolutions steps for same.
Please replace you dependency with below .
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-inline</artifactId>
<version>4.5.1</version>
<scope>test</scope>
</dependency>
if use 4.5.1 or latest your code will work
Also use your try with resource to mock static method
try (MockedStatic<WelcomeUtil> theMock = Mockito.mockStatic(WelcomeUtil.class)) {
theMock.when(() -> WelcomeUtil.generateWelcome("John"))
.thenReturn("Guten Tag John");
assertEquals("Guten Tag John", WelcomeUtil.generateWelcome("John"));
}
Upvotes: 7
Reputation: 1748
Add the following per https://www.baeldung.com/mockito-mock-static-methods:
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-inline</artifactId>
<version>3.8.0</version>
<scope>test</scope>
</dependency>
Upvotes: 13
Reputation: 4779
In my case we were using spring boot and below dependency for spring-boot-starter-test and mockito-core was coming internally with spring-boot-starter-test
testImplementation 'org.springframework.boot:spring-boot-starter-test'
use gradle dependencies to find this
+--- org.springframework.boot:spring-boot-starter-test -> 2.6.6
| +--- org.springframework.boot:spring-boot-starter:2.6.6 (*)
| +--- org.springframework.boot:spring-boot-test:2.6.6
| | \--- org.springframework.boot:spring-boot:2.6.6 (*)
| +--- org.springframework.boot:spring-boot-test-autoconfigure:2.6.6
| | +--- org.springframework.boot:spring-boot:2.6.6 (*)
| | +--- org.springframework.boot:spring-boot-test:2.6.6 (*)
| | \--- org.springframework.boot:spring-boot-autoconfigure:2.6.6 (*)
| +--- com.jayway.jsonpath:json-path:2.6.0
| | +--- net.minidev:json-smart:2.4.7 -> 2.4.8
| | | \--- net.minidev:accessors-smart:2.4.8
| | | \--- org.ow2.asm:asm:9.1 -> 9.3
| | \--- org.slf4j:slf4j-api:1.7.30 -> 1.7.36
| +--- jakarta.xml.bind:jakarta.xml.bind-api:2.3.3
| | \--- jakarta.activation:jakarta.activation-api:1.2.2
| +--- org.assertj:assertj-core:3.21.0
| +--- org.hamcrest:hamcrest:2.2
| +--- org.junit.jupiter:junit-jupiter:5.8.2
| | +--- org.junit:junit-bom:5.8.2
| | | +--- org.junit.jupiter:junit-jupiter:5.8.2 (c)
| | | +--- org.junit.jupiter:junit-jupiter-api:5.8.2 (c)
| | | +--- org.junit.jupiter:junit-jupiter-params:5.8.2 (c)
| | | \--- org.junit.platform:junit-platform-commons:1.8.2 (c)
| | +--- org.junit.jupiter:junit-jupiter-api:5.8.2
| | | +--- org.junit:junit-bom:5.8.2 (*)
| | | +--- org.opentest4j:opentest4j:1.2.0
| | | +--- org.junit.platform:junit-platform-commons:1.8.2
| | | | +--- org.junit:junit-bom:5.8.2 (*)
| | | | \--- org.apiguardian:apiguardian-api:1.1.2
| | | \--- org.apiguardian:apiguardian-api:1.1.2
| | \--- org.junit.jupiter:junit-jupiter-params:5.8.2
| | +--- org.junit:junit-bom:5.8.2 (*)
| | +--- org.junit.jupiter:junit-jupiter-api:5.8.2 (*)
| | \--- org.apiguardian:apiguardian-api:1.1.2
| +--- org.mockito:mockito-core:4.0.0
| | +--- net.bytebuddy:byte-buddy:1.11.19 -> 1.11.22
| | \--- net.bytebuddy:byte-buddy-agent:1.11.19 -> 1.11.22
| +--- org.mockito:mockito-junit-jupiter:4.0.0
| | \--- org.mockito:mockito-core:4.0.0 (*)
So, 2 steps to solve this issue.
Exclude the mockito-core from spring-boot-starter-test
testImplementation ('org.springframework.boot:spring-boot-starter-test')
{
exclude group: 'org.mockito', module :'mockito-core'
}
And now include the mockito-inline
testImplementation 'org.mockito:mockito-inline:4.6.1'
This will solve the issue.
Upvotes: 19
Reputation: 667
You need to use mockito-inline
version 3.4.0
or higher and remove mockito-core
from your dependencies (mockito-inline
depends on mockito-core
so it will be retrieved automatically).
That way, you will be using mockito static mocking correctly, but it wouldn't solve the exception that you posted.
To fix it, you need to remove all dependencies of powermock
as it conflicts with mockito
and causes this error
The used MockMaker PowerMockMaker does not support the creation of static mocks
Upvotes: 27
Reputation: 1467
You have to add /mockito-extensions/org.mockito.plugins.MockMaker file to the class path containing the value mock-maker-inline. Easiest way to do that is put it in the src/test/resources directory.
For more details check the Mockito documentation.
https://javadoc.io/doc/org.mockito/mockito-core/latest/org/mockito/Mockito.html#Mocking_Final
Upvotes: 9