在我的模拟类中,我正在模拟方法foo().对于某些测试用例,我希望foo()的模拟实现返回一个特殊值.对于其他测试用例,我想使用foo()的实际实现.我在我的mock类中定义了一个布尔值,以便我可以在mock方法中确定是否要返回特殊值,或者使用"real"方法.问题是,我似乎无法弄清楚如何从模拟方法调用真正的方法.
我发现你可以在名为"it"的模拟对象中定义一个特殊成员(具有被模拟对象的类型).这允许您从模拟实现中引用真实类.所以,我的计划是,如果我需要调用foo()的"真正"实现,mock方法将调用it.foo().但是,这不起作用,因为调用it.foo()只是再次调用模拟版本,而不是真实版本,所以我最终得到无限递归.
有没有办法使这项工作?
编辑:使用代码示例可能更清楚,这是我当前的模拟方法实现的样子:
private RealClass it;
...
public SomeClass foo() {
if(fakeIt) {
return new SomeClass("fakevalue");
} else {
// doesn't work, just keeps calling the mock foo
// in infinite recursion
return it.foo();
}
}
Run Code Online (Sandbox Code Playgroud)
编辑2:此外,对于我的大多数测试用例,我不想要模拟实现.所以我最初的尝试是在我需要模拟对象的那些测试用例中只调用Mockit.redefineMethods().但这不起作用 - 似乎你只能在setup/teardown中做到这一点......当我尝试时,我的模拟实现从未被调用过.
解决方案说明:
起初我并不认为给出的答案有效,但在使用它之后,似乎问题在于我将JMockit"核心"方法与"注释"驱动方法混合在一起.显然,在使用注释时,您需要使用Mockit.setupMocks,而不是Mockit.redefineMethods().这是最终奏效的:
@Before
public void setUp() throws Exception
{
Mockit.setUpMocks(MyMockClass.class);
}
Run Code Online (Sandbox Code Playgroud)
然后,对于模拟类:
@MockClass(realClass = RealClass.class)
public static class MyMockClass {
private static boolean fakeIt = false;
private RealClass it;
@Mock(reentrant = true)
public SomeClass foo() {
if(fakeIt) { …
Run Code Online (Sandbox Code Playgroud) 我有一个静态方法的类,我目前正在使用JMockit进行模拟.说它看起来像:
public class Foo {
public static FooValue getValue(Object something) {
...
}
public static enum FooValue { X, Y, Z, ...; }
}
Run Code Online (Sandbox Code Playgroud)
我有另一个类(让我们称之为MyClass)调用Foo的静态方法; 我正在尝试为这个类编写测试用例.我的JUnit测试,使用JMockit,看起来像这样:
public class MyClassTest extends TestCase {
@NonStrict private final Foo mock = null;
@Test public void testMyClass() {
new Expectations() {
{
Foo.getValue((Object) any); result = Foo.FooValue.X;
}
};
}
myClass.doSomething();
}
Run Code Online (Sandbox Code Playgroud)
这工作正常,花花公子,当测试执行时,我的MyClass实例将在调用Foo.getValue()时正确获取Foo.FooValue.X的枚举值.
现在,我正在尝试迭代枚举中的所有值,并重复运行测试.如果我将上面的测试代码放在for循环中并尝试将模拟静态方法的结果设置为每个枚举值,那么这不起作用.Foo.getValue()的模拟版本总是返回Foo.FooValue.X,并且在迭代枚举时从不返回任何其他值.
如何在单个JUnit测试中多次模拟静态方法?我想做这样的事情(但显然它不起作用):
public class MyClassTest extends TestCase {
@NonStrict private final Foo mock = null;
@Test public void testMyClass() …
Run Code Online (Sandbox Code Playgroud) 我有一个对象,我正在我的测试类NonStrictExcpection()
的@Before
/ setUp()
方法中使用JMockit进行模拟,以便它返回正常执行我的测试类所需的值.
这对我的所有测试方法都很好,除了我想要测试此代码的非正常操作的单个测试.
我已经尝试在测试方法中创建一个新的期望,我认为它会覆盖setUp方法中的期望,但我发现setUp方法中的期望抑制了新的期望.
当我删除setUp期望时,测试方法的行为与预期一致(但我所有其他测试自然都失败了).
我应该如何对我的测试类进行编码,以便能够以最少的代码量为每个测试正确定义期望值?(我知道我可以将期望代码复制/粘贴到每个测试方法中,但如果完全可以避免,我不想这样做).
我的测试代码看起来像这样(注意,这是sorta伪代码并且不能编译,但你明白了):
public class TestClass{
@Before
public void setUp(){
// Here I define the normal behaviour of mockObject
new NonStrictExpectations() {{
mockObject.doSomething();
result = "Everyting is OK!";
}};
// Other set up stuff...
}
// Other Tests...
/**
* This method tests that an error when calling
* mockObject.doSomething() is handled correctly.
*/
@Test(expected=Exception.class)
public void testMockObjectThrowsException(){
// This Expectation is apparently ignored... …
Run Code Online (Sandbox Code Playgroud) 我试图从Ant脚本运行JUnit测试.测试使用JMockit模拟框架,对于Java 5,它需要将其指定为javaagent才能正确运行.这是我正在运行的脚本:
<!DOCTYPE project>
<project name="junit_test">
<property name="PROJECT_PATH" value="{Path to my eclipse project}" />
<property name="LIB_PATH" value="${PROJECT_PATH}/WebContent/WEB-INF/lib" />
<property name="TEST_PATH" value="WebContent/WEB-INF/classes" />
<target name="run_junit">
<junit fork="yes" forkmode="once" printsummary="true">
<jvmarg value="-javaagent:${LIB_PATH}/jmockit.jar" />
<classpath path="${LIB_PATH}/jmockit.jar" />
<classpath path="${LIB_PATH}/junit-4.8.2.jar" />
<batchtest>
<fileset dir="${TEST_PATH}">
<include name="**/*Test.class"/>
</fileset>
</batchtest>
</junit>
<junitreport todir="/junitOut">
<fileset dir="/junitOut">
<include name="INCOMPLETE-*.xml"/>
<include name="TEST-*.xml"/>
</fileset>
<report todir="/junitOut/html"/>
</junitreport>
</target>
</project>
Run Code Online (Sandbox Code Playgroud)
我有一种感觉,我没有正确设置javaagent.此异常的测试错误:
java.lang.reflect.InvocationTargetException
at java.lang.reflect.Constructor.newInstance(Constructor.java:515)
at org.eclipse.ant.internal.ui.antsupport.EclipseDefaultExecutor.executeTargets(EclipseDefaultExecutor.java:32)
at org.eclipse.ant.internal.ui.antsupport.InternalAntRunner.run(InternalAntRunner.java:423)
at org.eclipse.ant.internal.ui.antsupport.InternalAntRunner.main(InternalAntRunner.java:137)
at java.lang.J9VMInternals.initialize(J9VMInternals.java:140)
at java.lang.J9VMInternals.initialize(J9VMInternals.java:140)
at java.lang.J9VMInternals.initialize(J9VMInternals.java:167)
Caused by: java.lang.RuntimeException: com.sun.tools.attach.AttachNotSupportedException: Unable …
Run Code Online (Sandbox Code Playgroud) 我的代码:
class A extends X {
@Autowired
B b;
@Override
method() {
//do something
b.callMethodInB;
//do something
}
}
class B extends X {
@Autowired
C c;
@Override
method() {
//do something
c.callMethodInC;
//do something
}
}
Run Code Online (Sandbox Code Playgroud)
我需要测试method()
在A
.那么如何模拟B
.我正在使用Junit4和Jmockit.
当我尝试运行 Junit 测试用例时,我遇到了异常。如果我正在更改类路径条目顺序,它工作正常,但 Jococo 覆盖不起作用。它正在挂起。任何人都可以帮助解决这个问题。
<classpathentry kind="lib" path="libt/junit-4.8.2.jar"/>
<classpathentry kind="lib" path="lib/jmockit.jar"/>
java.lang.IllegalStateException: JMockit wasn't properly initialized; check that jmockit.jar precedes junit.jar in the classpath (if using JUnit; if not, check the documentation)
at com.amica.bc.testutil.BillingCenterTestUtil$1.<init>(BillingCenterTestUtil.java:18)
at com.amica.bc.testutil.BillingCenterTestUtil.setCurrentUserName(BillingCenterTestUtil.java:18)
at amica.util.logging.TestAmicaGWLogger.setUp(TestAmicaGWLogger.java:36)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)
Run Code Online (Sandbox Code Playgroud) 有没有人能够从Maven构建的JaCoCo中获得JMockit和Powermock单元测试的单元测试覆盖率?
我有一个Powermock单元测试的现有测试集,我想逐步迁移到JMockit.但我需要能够在一份报告中看到所有单元测试的测试覆盖率,最好是在Sonar中.
通过将JaCoCo置于"离线"模式,我确实让JMockit和Powermock测试与Surefire/JaCoCo一起运行(否则我遇到了一个问题,其中一个代理在测试结束时没有被终止,然后mvn clean无法删除在下次运行时生成目标\ surefire\surefirebooter2967126910681005991.jar).但是没有为JMockit测试生成覆盖范围.
如果你有这个工作,请发布你的pom的一些摘录.
这就是我的pom的样子(注意surefire插件与reuseForks = false一致,以解决Powermock中的PermGen内存泄漏问题,这是迁移到JMockit的主要原因之一)
<profile>
<!-- use this profile to perform Sonar analysis -->
<id>sonar</id>
<properties>
<sonar.language>java</sonar.language>
<!-- Tells Sonar to use the generated test coverage report -->
<sonar.dynamicAnalysis>reuseReports</sonar.dynamicAnalysis>
<!-- Tells Sonar to use JaCoCo as the code coverage tool -->
<sonar.java.coveragePlugin>jacoco</sonar.java.coveragePlugin>
<sonar.java.codeCoveragePlugin>jacoco</sonar.java.codeCoveragePlugin>
</properties>
<build>
<plugins>
<!-- surefire (junit) plugin config with JaCoCo listener -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.16</version>
<configuration>
<!-- note: use single JVM to append …
Run Code Online (Sandbox Code Playgroud) 我看到记录器已经在Powermock的帮助下被嘲笑,或者某种被覆盖的构造函数需要记录器.
作为记录器在整个代码中使用,是不是他们使用mockito的简单方法?某种方式忽略调用或模拟它 - 我不想验证任何消息,只是想避免空指针异常
我是嘲笑框架的新手,所以我想知道使用Jmockit而不是混合和匹配两个库 - 到目前为止避免jomockit的唯一理由 - 太强大而且很容易被滥用!
我尝试将我的项目从 JDK 11 升级到 JDK 14,但在将 java 版本设置为 14 后运行测试失败。由于我将 jacoco 与 JMockit 结合使用,我配置了我的构建如下(编辑:JaCoCo 版本是 0.8.3 / 0.8.5,JMockit 版本 1.49):
<build>
<plugins>
<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<version>${version.jacoco}</version>
<executions>
<execution>
<id>coverage-initialize</id>
<goals>
<goal>prepare-agent</goal>
</goals>
</execution>
<execution>
<id>coverage-report</id>
<phase>post-integration-test</phase>
<goals>
<goal>report</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>${version.surefire-plugin}</version>
<configuration>
<argLine>
@{argLine} -javaagent:"${settings.localRepository}"/org/jmockit/jmockit/${version.jmockit}/jmockit-${version.jmockit}.jar
</argLine>
</configuration>
</plugin>
...
Run Code Online (Sandbox Code Playgroud)
如果我在 Java 版本设置为 11 的情况下运行 Maven,一切正常,但是当我将 Java 版本设置为 14 时,surefire 插件会抛出此错误:
[ERROR] java.lang.instrument.IllegalClassFormatException: Error while instrumenting sun/util/resources/cldr/provider/CLDRLocaleDataMetaInfo.
[ERROR] at org.jacoco.agent.rt.internal_1f1cc91.CoverageTransformer.transform(CoverageTransformer.java:93)
[ERROR] sun.util.locale.provider.LocaleDataMetaInfo: Unable to load sun.util.resources.cldr.provider.CLDRLocaleDataMetaInfo …
Run Code Online (Sandbox Code Playgroud) 我正在使用 Junit 3.8.1 并将 Jmokit 更新到 1.49
我有一个项目,其中现有测试与 MockUp 一起呈现。私有方法被嘲笑。将 Jmockit jar 更新到 1.49 版本后出现错误如下
java.lang.IllegalArgumentException: Unsupported fake for private method
Run Code Online (Sandbox Code Playgroud)
我要测试的 Java 类是
public class Foo {
String aVar;
public Foo(String str) {
aVar = str;
}
private void concatStr(String append) {
aVar = aVar.concat(append);
}
public void doSomeTask() {
concatStr("Test");
}
}
Run Code Online (Sandbox Code Playgroud)
测试类是
public class FooTest extends TestCase {
public FooTest(String testName) {
super(testName);
}
public static Test suite() {
return new TestSuite(FooTest.class);
}
public void test() { …
Run Code Online (Sandbox Code Playgroud)