[英]Why does using mockito-junit-jupiter and mockito-inline together in Groovy, results in InvalidUseOfMatchersException?
[英]Why do my Mockito-inline JUnit tests crash when run through Ant, and succeed in IntelliJ IDEA?
由于各种原因,我已经开始使用 Mockito 在我的单元测试中模拟一些类,并且随着我的开发,我得到了一切工作。 完成更改后,我推送到我们的构建服务器,发现通过 Ant 运行时单元测试被破坏。 我已经能够在一个简单的精简案例中重现这一点,其中我使用 Mockito 来测试模拟 static 方法的 class 的依赖关系。 下面我粘贴了源文件、测试文件、Ant 脚本和描述我正在使用的每个库的版本的 Ivy 依赖项文件(此时所有这些都是最新的),然后是详细错误 I看到了
但是,如果我在一个目录中创建这几个文件(使用src/com/example
下的两个类和tests/com/example
下的单元测试并将其作为 IntelliJ IDEA 项目打开,使用所有相同的依赖项(包括 JUnit)并运行所有测试,它成功了。与标准模块模板的唯一变化是指定JDK路径和Java级别为1.8。这是让它如此令人费解的部分原因。对于它的价值,Ant是否从Intelli内部调用都一样IDEA 的内置 Ant 集成,或者单独在命令行上。
package com.example;
public class BusinessClass {
public String returnString() {
StaticDependency.DoSomething();
return "Answer";
}
}
package com.example;
public class StaticDependency {
public static void DoSomething() {
throw new RuntimeException("Real code causes side effects I'm isolating from");
}
}
package com.example;
import org.junit.Test;
import org.mockito.MockedStatic;
import static org.junit.Assert.assertEquals;
import static org.mockito.Mockito.mockStatic;
public class BusinessClassTest {
@Test
public void returnString() {
final BusinessClass classUnderTest = new BusinessClass();
try (final MockedStatic<StaticDependency> ignored = mockStatic(StaticDependency.class)) {
assertEquals("Answer", classUnderTest.returnString());
}
}
}
<ivy-module version="2.0">
<info organisation="com.example" module="MockitoTest"/>
<dependencies>
<dependency org="junit" name="junit" rev="4.13.2"/>
<!-- Mockito and dependencies -->
<dependency org="org.mockito" name="mockito-inline" rev="4.2.0"/>
<dependency org="net.bytebuddy" name="byte-buddy-dep" rev="1.12.6"/>
<dependency org="org.objenesis" name="objenesis" rev="3.2"/>
</dependencies>
</ivy-module>
<project default="all" xmlns:ivy="antlib:org.apache.ivy.ant">
<property name="lib" location="Lib"/>
<property name="src" location="src"/>
<property name="tests" location="tests"/>
<property name="build-test" location="build-test"/>
<property name="build" location="build"/>
<path id="build.classpath">
<fileset dir="${lib}">
<include name="**/*.jar"/>
</fileset>
</path>
<target name="all" depends="clean, resolve, compile, test"/>
<target name="clean">
<delete dir="${build}"/>
<delete dir="${build-test}"/>
<delete dir="${lib}"/>
</target>
<target name="resolve" description="Download dependencies">
<ivy:resolve file="ivy.xml"/>
<mkdir dir="${lib}"/>
<ivy:retrieve pattern="${lib}/[artifact]-[type].[ext]"/>
</target>
<target name="compile" description="Compile the source code">
<mkdir dir="${build}"/>
<javac destdir="${build}">
<src path="${src}"/>
<classpath refid="build.classpath"/>
</javac>
<mkdir dir="${build-test}"/>
<javac destdir="${build-test}">
<src path="${src}"/>
<src path="${tests}"/>
<classpath refid="build.classpath"/>
</javac>
</target>
<target name="test" depends="compile" description="Run all unit tests">
<junit>
<classpath>
<path refid="build.classpath"/>
<path path="${build-test}"/>
</classpath>
<formatter type="plain" usefile="false"/>
<test name="com.example.BusinessClassTest" />
</junit>
</target>
</project>
Testsuite: com.example.BusinessClassTest
Tests run: 1, Failures: 0, Errors: 1, Skipped: 0, Time elapsed: 0.889 sec
Testcase: returnString took 0.779 sec
Caused an ERROR
Could not modify all classes [class com.example.StaticDependency]
org.mockito.exceptions.base.MockitoException: Could not modify all classes [class com.example.StaticDependency]
at com.example.BusinessClassTest.returnString(Unknown Source)
Caused by: java.lang.IllegalStateException:
Byte Buddy could not instrument all classes within the mock's type hierarchy
This problem should never occur for javac-compiled classes. This problem has been observed for classes that are:
- Compiled by older versions of scalac
- Classes that are part of the Android distribution
at org.mockito.internal.creation.bytebuddy.InlineBytecodeGenerator.triggerRetransformation(InlineBytecodeGenerator.java:280)
at org.mockito.internal.creation.bytebuddy.InlineBytecodeGenerator.mockClassStatic(InlineBytecodeGenerator.java:221)
at org.mockito.internal.creation.bytebuddy.TypeCachingBytecodeGenerator.mockClassStatic(TypeCachingBytecodeGenerator.java:63)
at org.mockito.internal.creation.bytebuddy.InlineDelegateByteBuddyMockMaker.createStaticMock(InlineDelegateByteBuddyMockMaker.java:560)
at org.mockito.internal.creation.bytebuddy.InlineByteBuddyMockMaker.createStaticMock(InlineByteBuddyMockMaker.java:83)
at org.mockito.internal.util.MockUtil.createStaticMock(MockUtil.java:147)
at org.mockito.internal.MockitoCore.mockStatic(MockitoCore.java:142)
at org.mockito.Mockito.mockStatic(Mockito.java:2164)
at org.mockito.Mockito.mockStatic(Mockito.java:2101)
Caused by: java.lang.AbstractMethodError: org.mockito.internal.creation.bytebuddy.InlineBytecodeGenerator$ParameterWritingVisitorWrapper.wrap(Lnet/bytebuddy/description/type/TypeDescription;Lorg/objectweb/asm/ClassVisitor;Lnet/bytebuddy/implementation/Implementation$Context;Lnet/bytebuddy/pool/TypePool;Lnet/bytebuddy/description/field/FieldList;Lnet/bytebuddy/description/method/MethodList;II)Lorg/objectweb/asm/ClassVisitor;
at net.bytebuddy.asm.AsmVisitorWrapper$Compound.wrap(AsmVisitorWrapper.java:746)
at net.bytebuddy.dynamic.scaffold.TypeWriter$Default$ForInlining$WithFullProcessing$RedefinitionClassVisitor.visit(TypeWriter.java:4906)
at org.objectweb.asm.ClassReader.accept(ClassReader.java:569)
at org.objectweb.asm.ClassReader.accept(ClassReader.java:424)
at net.bytebuddy.dynamic.scaffold.TypeWriter$Default$ForInlining.create(TypeWriter.java:3951)
at net.bytebuddy.dynamic.scaffold.TypeWriter$Default.make(TypeWriter.java:2213)
at net.bytebuddy.dynamic.scaffold.inline.RedefinitionDynamicTypeBuilder.make(RedefinitionDynamicTypeBuilder.java:224)
at net.bytebuddy.dynamic.scaffold.inline.AbstractInliningDynamicTypeBuilder.make(AbstractInliningDynamicTypeBuilder.java:123)
at net.bytebuddy.dynamic.DynamicType$Builder$AbstractBase.make(DynamicType.java:3661)
at org.mockito.internal.creation.bytebuddy.InlineBytecodeGenerator.transform(InlineBytecodeGenerator.java:394)
at sun.instrument.TransformerManager.transform(TransformerManager.java:188)
at sun.instrument.InstrumentationImpl.transform(InstrumentationImpl.java:428)
at sun.instrument.InstrumentationImpl.retransformClasses0(Native Method)
at sun.instrument.InstrumentationImpl.retransformClasses(InstrumentationImpl.java:144)
at org.mockito.internal.creation.bytebuddy.InlineBytecodeGenerator.triggerRetransformation(InlineBytecodeGenerator.java:276)
事实证明我的问题是我的ivy.xml
文件中适得其反的byte-buddy-dep
依赖。 正如@temp-droid在GitHub 问题中指出的那样,我在 Mockito 项目中提出了同样的问题,将其替换为byte-buddy
和byte-buddy-agent
将起作用。
然后我意识到 Ivy 不需要我明确列出子依赖项(我不知道它知道如何解决它们),因此我能够更新到这个更简单的ivy.xml
,它适用于 Ant 和IntelliJ 类似:
<ivy-module version="2.0">
<info organisation="com.example" module="MockitoTest"/>
<dependencies>
<dependency org="junit" name="junit" rev="4.13.2"/>
<dependency org="org.mockito" name="mockito-inline" rev="4.2.0"/>
</dependencies>
</ivy-module>
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.