2015-05-20 19 views
0

我使用工厂模式。我有3种货币:美元,RON和欧元。在每本类的我有同样的功能,打印,不同的输出:如何测试在jUnit的控制台上打印的void方法?

public void print() { 
    System.out.println("I printed dollars!"); 

} 

    public void print() { 
    System.out.println("I printed euro!");} 

在我的工厂类,我有回到货币类型的新对象的方法:

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; 
} 

现在,在我的测试类,我试过这个:

FabricaBani fabrica = new FabricaBani(); 
    Valuta valuta = fabrica.getValuta("dolar"); 
    valuta.tipareste(); 
    assertEquals("I printed dollars!", valuta.print()); 

我得到一个错误,说我不能测试一个字符串与void。我试过在valuta.print之后放入.toString,但我不允许。

+6

基本上,你已经编写了很难测试的代码。例如,如果您改变类来覆盖'toString()',或者让'print'接受'Writer',那么测试起来会更容易。 –

+0

尝试在'System.out.println()'之后的'print()'方法中返回字符串值。你的断言将使用返回值并将其输出到控制台输出。 – Kapcash

+0

@Jon Skeet对不起,但我不理解你。你能更具体一点吗? –

回答

2

valuta方法不返回任何东西,这就是为什么valuta.print()不能是你输出到控制台的字符串。

如果你想测试这个值,你可以重构你的方法来返回字符串,而不是输出它;那么你会在调用print()的方法中打印返回的String。

public String print() { 
    return "I printed dollars!"; 
} 

public void print() { 
    return "I printed euro!"; 
} 

然后,你会打电话像这样的打印输出到控制台

System.out.println(valuta.print()); 

您可以将打印方法可能重命名为getCurrency更好地表达方法做什么。

+0

谢谢。我不得不改变几乎每个班级,但它的工作! –

1

您可以编写一个测试,要求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); 
} 

Demo.

这是很不理想,当你有没有其他的方法只应该用于测试相关功能 - 例如,当您无法控制执行输出的部分代码时。另一方面,这种方法可以测试必须进行一些打印的代码的副作用,因此在测试必须确保输出为System.out的情况下,这可能是相关的。

+0

您可以使用[System Rules](http://stefanbirkner.github.io/system-rules/)库的SystemOutRule来代替自己实现代码。 –

0

这种情况的一个好的替代方案可能是延长美元(或一个人的继承类)进行测试。然后,在调用print()方法时,可以存储打印的最后一个字符串。

// Inside class extending Dollar, for example 
// public class TestDolar extends Dollar 
@Override 
public void print() { 
    _printedMessage = Valuta.DOLLAR_MESSAGE 
} 

这可能意味着你可以储存打印信息的Valuta公司,或在单独的类。

//Inside Dollar 
public void print() { 
    System.out.println(Valuta.DOLLAR_MESSAGE); 
} 

//Inside Valuta 
public static final String DOLLAR_MESSAGE = "I printed dollars!";