如何使用Scanner和while循环[复制]对void方法进行JUnit测试

问题描述 投票:1回答:2

这个问题在这里已有答案:

我想使用参数[-1,0,24,2,32]测试方法setDay()。

我知道Scanner读卡器可以

String test="-1 0 24 2 32"; Scanner reader=new Scanner(test);

主要问题是无限循环和无效方法。我们如何测试这种代码?这是示例代码:

public NameOfTheDay(){
   int day=1;     
}
{...}
public void setDay(Scanner reader) {
    while (true) {
        System.out.print("Day: ");
        String input = reader.nextLine();
        if (input.matches("\\d{2}")) {
            int day = Integer.parseInt(input);
            if (day > 0 && day < 32) {
                this.day = day;
                return;
            }
        }
        System.out.println("Wrong day. Try again.");
    }
}

谢谢你的回答。

java unit-testing while-loop void junit5
2个回答
1
投票

我不会关注您的方法的内容,而只关注如何对希望Scanner对象作为参数的方法进行单元测试的问题。

答案很简单:将测试输入数据作为String提供,并在其周围构建扫描程序,如下所示:

@Test
public void testSetDay_positive() {
    String testInput = "23\n";
    Scanner testScanner = new Scanner(testInput);
    NameOfTheDay notd = new NameOfTheDay();
    notd.setDay(testScanner);
    Assert.assertEquals(23, notd.getDay()); // or whatever condition to test
}

现在变得更难了。也许您想首先测试无效输入,并确保使用第二个输入?

@Test
public void testSetDay_negative_then_positive() {
    String testInput = "999\n23\n"; // two lines of input here
    Scanner testScanner = new Scanner(testInput);
    NameOfTheDay notd = new NameOfTheDay();
    notd.setDay(testScanner);
    Assert.assertEquals(23, notd.getDay()); // or whatever condition to test
}

如果要测试是否将错误消息写入System.out,则必须将其替换为自定义流以进行后续测试:

ByteArrayOutputStream mockOut = new ByteArrayOutputStream();
PrintStream newOut = new PrintStream(mockOut);
System.setOut(newOut);
// execute test from above
Assert.assertTrue(new String(mockOut.toByteArray(), "UTF-8").contains("Wrong day. Try again."));

尽管如此,对您的问题的大多数评论都包含有价值的输入(移动验证到额外的方法等)应该考虑。


1
投票

我们如何测试这种代码?

你不能。

unittest验证您的代码在测试中的公共可观察行为,其中“公共可观察行为”是任何rreturn值或与依赖项的通信。

使用测试双精度检查与依赖项的通信,我们(通常)使用模拟框架创建测试双精度并将其注入到测试中的代码中。

一个主要的先决条件是您的代码干净地包含单一责任/分离关注模式。

您的代码不会返回任何内容,也不可能替换感兴趣的依赖项(此处为System.out),因为它将业务逻辑与用户交互混合在一起。


有些人可能会争辩说,你可以为System.out分配测试双或使用 PowerMock 替换依赖项,但恕我直言,这只是你的糟糕设计投降,并不会随着你的程序增长而得到回报。

© www.soinside.com 2019 - 2024. All rights reserved.