如何测试不带参数的 Void 方法,将行打印到控制台

How to Test Void Method With No Arguments That Prints Line to Console

为了家庭作业,我创建了一个名为 Bird 的 Class,其中包含一个方法:

public void launch()
{
     System.out.println("Flapping the wings until take-off");
}

我需要 运行 对所有包含的方法进行 jUnit 测试,包括这些方法。但是,当我使用:

@Test
    void testLaunch()
    {
        Bird myBird = new Bird("Macaw");
        assertEquals("Flapping the wings to take-off", myBird.launch());
    }

我在 Eclipse 中遇到此错误:"The method assertEquals(short, short) in the type Assertions is not applicable for the arguments (String, void)"

我很沮丧,因为我们的老师没有教我们如何测试这些方法,他也从不回复我寻求帮助的电子邮件。即使这被认为是一个整体薄弱的问题,任何帮助将不胜感激。

您可以使用 System.setOut(PrintStream) 暂时将 标准输出 替换为 ByteArrayOutputStream 支持的内存 PrintStream 并使用它来获取输出。像,

@Test
void testLaunch() {
    PrintStream original = System.out;
    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    PrintStream tps = new PrintStream(baos);
    Bird myBird = new Bird("Macaw");
    System.setOut(tps);
    myBird.launch();
    System.setOut(original);
    tps.flush();
    assertEquals("Flapping the wings to take-off", baos.toString());
}

通常你只测试其中有某种逻辑的方法。调用 System.out.println 不被认为是逻辑。

从测试驱动的角度来看,使用无副作用的方法更容易,因为它们采用一些参数并 return 结果,您的方法恰恰相反,因此非常很难测试。

在你的案例中唯一可行的方法(除了声明你的方法不够复杂,无法测试)是将你的方法分成一个创建 String 的方法(该方法可以测试)和调用另一个方法并打印结果的方法(调用另一个方法(在另一个 class 中称为服务)可以使用各种框架(例如 Mockito)进行测试。调用 System.out.println 很难测试,您可以为 Stream (System.out) 提取 Supplier 并验证它 return 确实 System.out 并再次验证 println 在提供的 Stream 上被调用。

查看此测试结构会指出一个事实,即基本方法不仅依赖于副作用,而且它同时做三件事(而理想的方法只做一件事)。它创建了一个 Object(这里是 String),它获取和 OutStream(这里是 System.out)并且它同时使用了两者(println)。

是的,这可能看起来过于复杂,但从学习的角度来看,它表明即使隐藏在像这样简单的东西中,也有很多复杂性,如果做得好,可以教授很多关于面向对象设计和清洁和 S.O.L.I.D。代码