在jdk21+版本中直接通过依赖库的方式使用Mockito(Mockito-inline)时会弹出警告
Mockito is currently self-attaching to enable the inline-mock-maker. This will no longer work in future releases of the JDK. Please add Mockito as an agent to your build as described in Mockito's documentation: https://javadoc.io/doc/org.mockito/mockito-core/latest/org.mockito/org/mockito/Mockito.html#0.3
WARNING: A Java agent has been loaded dynamically (/Users/fqy/.gradle/caches/modules-2/files-2.1/net.bytebuddy/byte-buddy-agent/1.17.7/fbf3d6d649ed37fc9e9c59480a05be0a26e3c2da/byte-buddy-agent-1.17.7.jar)
WARNING: If a serviceability tool is in use, please run with -XX:+EnableDynamicAgentLoading to hide this warning
WARNING: If a serviceability tool is not in use, please run with -Djdk.instrument.traceUsage for more information
WARNING: Dynamic loading of agents will be disallowed by default in a future release
即在以后的jdk发行版本中会移除动态agnet加载的支持!
此时需要通过javaagent的方式来使用mockito,使用方式如下:
在gradle中
配置
- 添加一个自定义配置mockitoAgent
configurations { mockitoAgent }
- 在dependencies块中向mockitoAgent配置中添加Mockito核心依赖
mockitoAgent(libs.mockito) { transitive = false }
- 在test块中读取到Mockito的jar绝对路径并作为jvm参数
jvmArgs += "-javaagent:${configurations.mockitoAgent.asPath}"
详细build.gradle配置如下:
plugins {
id 'groovy'
id 'java'
}
group = 'local.my'
version = '1.0-SNAPSHOT'
sourceSets {
main {
groovy {
srcDirs = ['src/main/groovy', 'src/main/java']
}
}
test {
groovy {
srcDirs = ['src/test/groovy', 'src/test/java']
}
}
}
repositories {
mavenCentral()
}
configurations {
/**创建一个名为mockitoAgent的自定义配置;
* 这个配置类似于implementation、testImplementation等,但是用户自定义的;
* 可以在构建脚本中单独引用这个配置中的依赖;*/
mockitoAgent
}
dependencies {
implementation 'org.apache.groovy:groovy:5.0.2'
testImplementation platform('org.junit:junit-bom:5.13.4')
testImplementation 'org.junit.jupiter:junit-jupiter'
testImplementation 'org.mockito:mockito-junit-jupiter:5.20.0'
testRuntimeOnly 'org.junit.platform:junit-platform-launcher'
//向mockitoAgent配置中添加Mockito核心依赖,并禁用传递依赖
mockitoAgent('org.mockito:mockito-core:5.20.0') { transitive = false }
}
tasks.withType(GroovyCompile).configureEach {
// 启用groovy的增量编译
options.incremental = true
options.incrementalAfterFailure = true
}
tasks.withType(JavaCompile).configureEach {
// 指定java版本
options.release = 25
}
test {
useJUnitPlatform()
// 配置运行测试用例时的JVM参数添加mockito javaagent
jvmArgs += "-javaagent:${configurations.mockitoAgent.asPath}"
println '>>>gradle版本: '+gradle.gradleVersion
println '>>>运行测试用例时的jvm参数: '+jvmArgs
// 测试输出配置
testLogging {
events "passed", "skipped", "failed", "standardOut", "standardError"
// 显示System.out和System.err的输出
showStandardStreams = true
showCauses = true
showExceptions = true
showStackTraces = true
exceptionFormat = 'full'
}
// 在控制台实时显示输出
outputs.upToDateWhen { false }
}
测试
首先准备一个被测试类Main.groovy
package local.my.demo_jdk
static String say(){
return 'Hello world!'
}
然后创建一个测试类Gv1Test.groovy
package local.my.demo_jdk.t
import local.my.demo_jdk.Main
import org.junit.jupiter.api.Test
import static org.mockito.Mockito.*
class Gv1Test {
@Test
void test1(){
println '开始测试-----'
println 'groovy version : '+GroovySystem.version
println 'before mock say'
println Main.say()
println 'after mock say'
try (def _ = mockStatic(Main).tap {
it.when {Main.say()}.thenReturn("mock say")
}){
println Main.say()
}
println '结束测试-----'
}
}
最后运行测试./gradlew test
输出日志如下:
> Configure project :
>>>gradle版本: 9.2.0
>>>运行测试用例时的jvm参数: [-javaagent:/Users/fqy/.m2/repository/org/mockito/mockito-core/5.20.0/mockito-core-5.20.0.jar]
> Task :test
Gv1Test > test1() STANDARD_OUT
开始测试-----
groovy version : 5.0.2
before mock say
Hello world!
after mock say
mock say
结束测试-----
Gv1Test > test1() PASSED
BUILD SUCCESSFUL in 1s
在maven中
- 在
pom.xml的build块的maven-surefire-plugin插件添加argLine配置@{argLine} -javaagent:${org.mockito:mockito-core:jar} - 在
pom.xml的build块的maven-dependency-plugin插件添加goal配置properties
完整的pom.xml配置如下:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>local.my</groupId>
<artifactId>demo_jdk_new</artifactId>
<version>1.0-SNAPSHOT</version>
<properties>
<maven.compiler.source>25</maven.compiler.source>
<maven.compiler.target>25</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-junit-jupiter</artifactId>
<version>5.20.0</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>properties</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<argLine>@{argLine} -javaagent:${org.mockito:mockito-core:jar}</argLine>
</configuration>
</plugin>
</plugins>
</build>
</project>
或者直接通过jvm参数-XX:+EnableDynamicAgentLoading在运行测试时允许动态加载agent
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<argLine>@{argLine} -XX:+EnableDynamicAgentLoading</argLine>
</configuration>
</plugin>
</plugins>
</build>