标签: jmockit

在JMockit中是否有一种方法可以从模拟方法中调用原始方法?

在我的模拟类中,我正在模拟方法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)

java jmockit mocking

6
推荐指数
2
解决办法
1万
查看次数

在JUnit测试中使用JMockit多次模拟静态方法

我有一个静态方法的类,我目前正在使用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)

java methods junit static jmockit

6
推荐指数
1
解决办法
1万
查看次数

在JMockit中删除先前定义的期望

我有一个对象,我正在我的测试类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)

unit-testing jmockit mocking

6
推荐指数
1
解决办法
2971
查看次数

在ant中设置javaagent

我试图从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)

java ant junit jmockit

6
推荐指数
1
解决办法
5456
查看次数

如何使用JMockit模拟spring注入的类

我的代码:

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.

java junit spring jmockit mocking

6
推荐指数
2
解决办法
4990
查看次数

java.lang.IllegalStateException:JMockit 未正确初始化;检查类路径中 jmockit.jar 是否在 junit.jar 之前

当我尝试运行 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)

code-coverage jmockit junit4

6
推荐指数
2
解决办法
1万
查看次数

Powermock和JMockit单元测试的测试范围

有没有人能够从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)

jmockit powermock surefire maven jacoco

6
推荐指数
1
解决办法
1535
查看次数

使用mockito在java服务中模拟静态记录器的策略是什么

我看到记录器已经在Powermock的帮助下被嘲笑,或者某种被覆盖的构造函数需要记录器.

作为记录器在整个代码中使用,是不是他们使用mockito的简单方法?某种方式忽略调用或模拟它 - 我不想验证任何消息,只是想避免空指针异常

我是嘲笑框架的新手,所以我想知道使用Jmockit而不是混合和匹配两个库 - 到目前为止避免jomockit的唯一理由 - 太强大而且很容易被滥用!

logging junit jmockit mockito

6
推荐指数
1
解决办法
8173
查看次数

Maven Surefire 插件与 Jacoco、JMockit 和 JDK14 的问题

我尝试将我的项目从 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)

jmockit maven jacoco java-14

6
推荐指数
1
解决办法
1万
查看次数

如何从 Jmokit 1.49 版本模拟私有方法

我正在使用 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)

junit jmockit mocking

6
推荐指数
1
解决办法
3130
查看次数