Java 用jmockit测试main方法

Java 用jmockit测试main方法,java,junit,tdd,jmockit,Java,Junit,Tdd,Jmockit,为了接近100%,我想测试一下主要的方法。 我只创建一个类的实例,它应该启动 应用程序。测试和代码如下所示: public class MainTest { @Test public void delegates_to_Launcher_instance(@Mocked Launcher launcher) { String[] args = {"i"}; Main.main(args); new Verifications() {

为了接近100%,我想测试一下主要的方法。 我只创建一个类的实例,它应该启动 应用程序。测试和代码如下所示:

public class MainTest {
    @Test
    public void delegates_to_Launcher_instance(@Mocked Launcher launcher) {
        String[] args = {"i"};
        Main.main(args);
        new Verifications() {{ launcher.run(args); }};
    }
}

public class Main {
    public static void main(String[] args) {
        new Launcher().run(args);
    }
}

public class Launcher {
    public void run(String[] args) {
    }
}
public class MainTest {
    @Test
    public void delegates_to_Main_instance(@Mocked Main main) {
        String[] args = {"i"};
        Main.main(args);
        new Verifications() {{ main.run(args); }};
    }
}

public class Main {
    public static void main(String[] args) {
        new Main().run(args);
    }
}
很好用

现在,Launcher类有点多余,覆盖率不是100%,因为Main的构造函数没有被调用。通过将代码从启动器移动到main,可以修复这两个问题,如下所示:

public class MainTest {
    @Test
    public void delegates_to_Launcher_instance(@Mocked Launcher launcher) {
        String[] args = {"i"};
        Main.main(args);
        new Verifications() {{ launcher.run(args); }};
    }
}

public class Main {
    public static void main(String[] args) {
        new Launcher().run(args);
    }
}

public class Launcher {
    public void run(String[] args) {
    }
}
public class MainTest {
    @Test
    public void delegates_to_Main_instance(@Mocked Main main) {
        String[] args = {"i"};
        Main.main(args);
        new Verifications() {{ main.run(args); }};
    }
}

public class Main {
    public static void main(String[] args) {
        new Main().run(args);
    }
}
但当我这样做时,JMockit抱怨:

Missing invocation to:
mmm.Main#run(["i"])
   on mock instance: mmm.Main@224aed64

    at mmm.MainTest$1.<init>(MainTest.java:15)
    at mmm.MainTest.delegates_to_Main_instance(MainTest.java:15)
Caused by: Missing invocation
    at mmm.Main.run(Main.java)
    ... 2 more
有人能解释一下,这里发生了什么事吗?

这里:

public void delegates_to_Main_instance(@Mocked Main main) {
你在嘲笑梅因。同时,您希望编写一个单元测试来练习该主要对象。那没有道理。您只模拟进入生产代码并且需要控制/验证的内容。您不会模拟要测试自身的对象


在第一个示例中,您使用的是一个模拟启动器,它将被传递给被测试的类。这很有道理。在第二个示例中,您传递了一个模拟实例,然后假设模拟实例是被测试的类。没什么意义。

无关:阅读Java命名约定。使用u仅适用于某些u常量-但u不用于方法名称!幽灵猫的回答是正确的。我只想补充一点,在这里使用嘲弄的整个想法是不好的。一个好的测试验证给定的类A解决了它应该解决的有意义的业务问题,而不是它调用了类B中的某个方法。此外,编写测试不应该是为了增加代码覆盖率,而是为了增加业务需求的覆盖率。否则,您将得到一系列测试,这些测试不仅没有什么价值,而且还会阻止您/其他人创建那些真正重要的测试。嘲笑只在特殊情况下有用——除此之外,它是有害的。