在这里对主要方法进行单元测试的正确方法是什么?理想情况下,我只想验证SomeProgram的(模拟)实例是否在main方法中调用了run()方法。我知道我可以创建一个setter来设置SomeProgram的实例,但它看起来像代码味道,因为它除了能够更容易测试之外什么都不做?与run()方法上的公共访问器相同。为了测试,它是自由的。如果它是私有的,我怎么测试呢?我正在寻找班级的变化,也许应用一些可以缓解这个问题的设计模式。
public class SomeProgram {
public void run(Dependency1 dependency1, Dependency2 dependency2) {
dependency1.doSomething();
dependency2.doSomething();
}
public static void main(String[] args) {
new SomeProgram().run(new Dependency1(), new Dependency2());
}
}
答案 0 :(得分:1)
对main
方法进行单元测试没有用处。通常,这些方法初始化一个对象图(或者显式调用像Spring或Guice这样的DI容器),因此你最终没有任何真正有用的测试接缝可以直接注入模拟或伪造。
您可以做的是使用集成测试。您可以设置集成环境并将main方法配置为指向受测试控制的事物。因此,例如,如果您的程序与数据库进行通信,那么您的测试可以启动嵌入式数据库并使用命令行参数将程序指向嵌入式数据库而不是外部数据库。您可以使用嵌入式Jetty伪装出外部Rest API。
但接受这些不是单位测试非常重要。它们是集成测试,并且会遇到通常与集成测试相关的问题 - 它们比单元测试慢,并且您对系统的控制较少,因此测试了一些东西可能很棘手。
答案 1 :(得分:0)
测试本程序的功能,而不是程序本身。
您可以通过利用依赖注入来实现此目的。如果Dependency1是一个接口而不是一个具体的类,这种方法效果最好。
public class SomeProgram
{
private final Dependency1 _dependency1;
private final Dependency2 _dependency2;
public SomeProgram(Dependency1 dependency1, Dependency2 dependency2)
{
_dependency1 = dependency1;
_dependency2 = dependency2;
}
public void run()
{
dependency1.doSomething();
dependency2.doSomething();
}
}
然后你的main方法就像单元测试一样,除了它会注入真正的依赖。
public static void main(String[] args)
{
new SomeProgram(new Dependency1(), new Dependency2()).run();
}