Java 如何在没有参数的情况下对void方法进行单元测试
我需要测试一个类,以确定在给定特定输入的情况下是否发生了相关操作。代码是这样的:Java 如何在没有参数的情况下对void方法进行单元测试,java,unit-testing,junit,switch-statement,mockito,Java,Unit Testing,Junit,Switch Statement,Mockito,我需要测试一个类,以确定在给定特定输入的情况下是否发生了相关操作。代码是这样的: protected static void receiveInput() { String command; boolean b = true; Scanner scanner = new Scanner(System.in); while (b) { command = scanner.next(); switch(command) {
protected static void receiveInput() {
String command;
boolean b = true;
Scanner scanner = new Scanner(System.in);
while (b) {
command = scanner.next();
switch(command) {
case "first":
System.out.println("First!");
break;
case "second":
System.out.println("Second!");
break;
case "third":
System.out.println("Third!");
break;
default:
System.out.println("\n***** Invalid *****\n");
}
System.out.println("\n");
}
scanner.close();
}
如果我能以某种方式控制命令字符串并跟踪scanner对象,我可能会得到一个非常彻底的单元测试。出于某种原因,我实际上不允许将这两个对象作为此方法的参数注入。以不同的方式进行此测试有哪些选项?这是一个使函数更易于测试的完美示例。这个功能不需要输入,也不产生输出,只通过副作用影响世界,通过标准手段使其完全不稳定 要重构此函数以使其更易于测试,请执行以下操作:
- 不要要求用户通过扫描仪输入,将用户的输入作为输入参数
- 不要打印结果,返回它
同样,使用重定向输出流。除了MattPutnam的优秀答案外,还有两个方法的具体提示 1.更改为返回字符串
protected static string receiveInput(String arg) {
String result;
String command = arg;
boolean b = true;
while (b) {
switch(command) {
case "first":
result = "first";
break;
case "second":
result = "second";
break;
case "third":
result = "third";
break;
default:
result = "\n ****Invalid*** \n";
}
}
return result;
}
2.我倾向于测试
布尔b
是否为真。如果是真的,你知道它起作用了,如果不是,它就没有作用Edit:请注意,这可能很危险,因为您不会检查arg
是否一定符合字符串标准,而是检查它是否有可接受的答案
测试当前方法的唯一方法是以某种方式捕获流,如注释中回答的MattPutnam。您可以使用库测试输出
完全公开:我是系统规则的作者。您不能将其作为
string
类型的值返回函数,而只返回要检查的特定case字符串?您是否能够更改此方法以使其更易于单元测试?这不是一个非常易于单元测试的方法。通常对我来说,当我对void方法进行单元测试时,这是因为它们会产生某种副作用或状态变化。然后我测试副作用是否正确发生。不幸的是,在这种情况下,不更改方法就很难进行单元测试。您可以将“业务逻辑”封装在一个可测试的方法中,该方法接受输入并返回输出,从而保持void
方法的完整性。可能更可取的是让该方法接受两个参数,即您提到的标准方法InputStream(或Reader)和OutputStream(或Writer,或PrintWriter)。这是否意味着还有其他方法进行单元测试?这正是我想要的。要按原样进行测试,必须截取输入和输出流。这是可以做到的,但它是丑陋的地狱。伟大的答案!有一本很棒的书,我建议大家,不管有多丰富的经验。。。干净的代码:Robert C.Martin的敏捷软件工艺手册…让我们假设我将尝试测试I/O。我将如何以捕获函数的方式编写它?仅仅证明布尔值是危险的。。。我建议将整个逻辑提取到一个自己的方法中,正如MattPutman所说……这就是为什么我把它列在第1位之后。我明白你为什么说现在我读了我的答案会很危险。我会编辑。@Milesperterson,我强烈建议你接受MattPutnam的回答
public class YourTest {
@Rule
public SystemOutRule log = new SystemOutRule().enableLog();
@Rule
public TextFromStandardInputStream systemInMock = emptyStandardInputStream();
@Test
public void test() {
systemInMock.provideLines("first", "second");
... //execute your code
assertEquals("First!\nSecond!\n", log.getLogWithNormalizedLineSeparator());
}
}