如何测试在 jUnit 控制台上打印的 void 方法?
How to test a void method that prints on console in jUnit?
我使用工厂模式。我有 3 种货币:美元、罗马尼亚列伊和欧元。在每个 classes 中,我都有相同的功能,打印,但输出不同:
public void print() {
System.out.println("I printed dollars!");
}
public void print() {
System.out.println("I printed euro!");}
在我的工厂 class 中,我有一个方法 return 一个新的货币类型对象:
public Valuta getValuta(String numeValuta){
if(numeValuta == null){
return null;
}
if(numeValuta.equalsIgnoreCase("dolar")){
return new Dolar();
}
if(numeValuta.equalsIgnoreCase("euro")){
return new Euro();
}
if(numeValuta.equalsIgnoreCase("lei")){
return new Lei();
}
return null;
}
现在,在我的测试 class 中,我尝试测试这个:
FabricaBani fabrica = new FabricaBani();
Valuta valuta = fabrica.getValuta("dolar");
valuta.tipareste();
assertEquals("I printed dollars!", valuta.print());
我收到一条错误消息,提示我无法测试带有 void 的字符串。我尝试在 valuta.print 之后放置 .toString,但不允许这样做。
方法 valuta 没有 return 任何东西,这就是为什么 valuta.print() 不能是您输出到控制台的字符串。
如果你想测试这个值,你可以将你的方法重构为 return 字符串而不是输出它;然后您将在调用 print().
的方法中打印 returned 字符串
public String print() {
return "I printed dollars!";
}
public void print() {
return "I printed euro!";
}
然后,你会像这样调用打印输出到控制台
System.out.println(valuta.print());
您可以将打印方法重命名为 getCurrency 以更好地表达该方法的作用。
您可以编写一个调用 setOut
来捕获打印输出的测试,如下所示:
private static void test() {
System.out.println("Hello, world!");
}
public static void main (String[] args) throws java.lang.Exception
{
String res = null;
PrintStream originalOut = System.out;
try {
ByteArrayOutputStream os = new ByteArrayOutputStream(100);
PrintStream capture = new PrintStream(os);
// From this point on, everything printed to System.out will get captured
System.setOut(capture);
test();
capture.flush();
res = os.toString();
} finally {
System.setOut(originalOut);
}
System.out.println("Captured output: "+res);
}
这远非理想,只有当您没有其他方法来测试相关功能时才应使用 - 例如,当您无法控制执行输出的部分代码时。
另一方面,这种方法可以让您测试必须进行一些打印的代码的副作用,因此在您的测试必须确保输出到 System.out
.
的情况下,它可能是相关的
对于这种情况,一个很好的替代方案可能是 扩展美元 (或一个人继承 class)以进行测试。然后,当调用 print() 方法时,您可以存储最后打印的字符串。
// Inside class extending Dollar, for example
// public class TestDolar extends Dollar
@Override
public void print() {
_printedMessage = Valuta.DOLLAR_MESSAGE
}
这可能意味着您可以将打印消息存储在 Valuta 或单独的 classes 中。
//Inside Dollar
public void print() {
System.out.println(Valuta.DOLLAR_MESSAGE);
}
//Inside Valuta
public static final String DOLLAR_MESSAGE = "I printed dollars!";
我使用工厂模式。我有 3 种货币:美元、罗马尼亚列伊和欧元。在每个 classes 中,我都有相同的功能,打印,但输出不同:
public void print() {
System.out.println("I printed dollars!");
}
public void print() {
System.out.println("I printed euro!");}
在我的工厂 class 中,我有一个方法 return 一个新的货币类型对象:
public Valuta getValuta(String numeValuta){
if(numeValuta == null){
return null;
}
if(numeValuta.equalsIgnoreCase("dolar")){
return new Dolar();
}
if(numeValuta.equalsIgnoreCase("euro")){
return new Euro();
}
if(numeValuta.equalsIgnoreCase("lei")){
return new Lei();
}
return null;
}
现在,在我的测试 class 中,我尝试测试这个:
FabricaBani fabrica = new FabricaBani();
Valuta valuta = fabrica.getValuta("dolar");
valuta.tipareste();
assertEquals("I printed dollars!", valuta.print());
我收到一条错误消息,提示我无法测试带有 void 的字符串。我尝试在 valuta.print 之后放置 .toString,但不允许这样做。
方法 valuta 没有 return 任何东西,这就是为什么 valuta.print() 不能是您输出到控制台的字符串。
如果你想测试这个值,你可以将你的方法重构为 return 字符串而不是输出它;然后您将在调用 print().
的方法中打印 returned 字符串public String print() {
return "I printed dollars!";
}
public void print() {
return "I printed euro!";
}
然后,你会像这样调用打印输出到控制台
System.out.println(valuta.print());
您可以将打印方法重命名为 getCurrency 以更好地表达该方法的作用。
您可以编写一个调用 setOut
来捕获打印输出的测试,如下所示:
private static void test() {
System.out.println("Hello, world!");
}
public static void main (String[] args) throws java.lang.Exception
{
String res = null;
PrintStream originalOut = System.out;
try {
ByteArrayOutputStream os = new ByteArrayOutputStream(100);
PrintStream capture = new PrintStream(os);
// From this point on, everything printed to System.out will get captured
System.setOut(capture);
test();
capture.flush();
res = os.toString();
} finally {
System.setOut(originalOut);
}
System.out.println("Captured output: "+res);
}
这远非理想,只有当您没有其他方法来测试相关功能时才应使用 - 例如,当您无法控制执行输出的部分代码时。
另一方面,这种方法可以让您测试必须进行一些打印的代码的副作用,因此在您的测试必须确保输出到 System.out
.
对于这种情况,一个很好的替代方案可能是 扩展美元 (或一个人继承 class)以进行测试。然后,当调用 print() 方法时,您可以存储最后打印的字符串。
// Inside class extending Dollar, for example
// public class TestDolar extends Dollar
@Override
public void print() {
_printedMessage = Valuta.DOLLAR_MESSAGE
}
这可能意味着您可以将打印消息存储在 Valuta 或单独的 classes 中。
//Inside Dollar
public void print() {
System.out.println(Valuta.DOLLAR_MESSAGE);
}
//Inside Valuta
public static final String DOLLAR_MESSAGE = "I printed dollars!";