如何对没有返回值但写入System.out的方法进行单元测试

时间:2014-02-27 12:01:33

标签: java junit

我想在下面的ForecastDisplay类上做一个没有返回值的JUnit测试。这个类的工作方式是currentPressure = 29.92f被测试器类中分配的新压力所取代。显示方法比较新旧压力并将适当的消息打印到控制台。由于这是一种无效方法,我不知道如何测试它。

例如:如果我在JUnit测试中指定了35的新currentPressure,那么将打印第一条消息,因为35> 29.92。如果有人可以建议如何测试这个我会很感激,因为到目前为止,我无法在不改变显示方法的情况下返回一个值,这是作弊,因为我不应该调整代码来通过一个JUnit测试。谢谢

public class ForecastDisplay implements Observer, DisplayElement {
private float currentPressure = 29.92f;  
private float lastPressure;
private WeatherData weatherData;

public ForecastDisplay(WeatherData weatherData) {
    this.weatherData = weatherData;
    weatherData.registerObserver(this);
}

public void update(float temp, float humidity, float pressure) {
    lastPressure = currentPressure;
    currentPressure = pressure;

    display();
}

public void display() {
    System.out.print("Forecast Display: ");
    if (currentPressure > lastPressure) {
        System.out.println("Improving weather on the way!");
    } else if (currentPressure == lastPressure) {
        System.out.println("More of the same");
    } else if (currentPressure < lastPressure) {
        System.out.println("Watch out for cooler, rainy weather");
    }
}


} 

6 个答案:

答案 0 :(得分:2)

就目前而言,您需要使用PowerMock这样的工具来模拟System.out,以确定该方法尝试打印的内容。如何解决制定消息(需要测试)和显示问题的担忧。

public String determineMessage() {
    String msg = "Forecast Display: ";
    if (currentPressure > lastPressure) {
        msg += "Improving weather on the way!";
    } else if (currentPressure == lastPressure) {
        msg += "More of the same";
    } else if (currentPressure < lastPressure) {
        msg += "Watch out for cooler, rainy weather";
    return msg;
 }

public void display() {
    System.out.println(determineMessage());
}

这种方式可以通过在类上设置各种压力并断言正确确定消息来完成单元测试。

答案 1 :(得分:2)

如果您不能像其他人建议的那样(并且我同意)将display()方法重构为最佳解决方案,那么您可以intercept System.out并在此基础上发表您的声明:

@Test
public void testDisplay()
{
    final ByteArrayOutputStream out = new ByteArrayOutputStream( 256 );
    PrintStream ps = new PrintStream( out );
    System.setOut( ps );
    Forecast f = new Forecast(...);
    f.update( ... );

    assertThat( "Expected whatever" , out.toString() , equalTo( "..." ) );
}

干杯,

答案 2 :(得分:2)

在Java中,你可以System.setOut(yourOutStream)使用它并执行@Before和@After来清理System.setOut(null)

private final ByteArrayOutputStream out = new ByteArrayOutputStream();
@Before
public void redirectOut() {
    System.setOut(new PrintStream(out));
}

@After
public void cleanUpOut() {
    System.setOut(null);
}

然后你可以测试它:

@Test
public void shouldUpdatePresure() {
    update(101.5, 80.0, 25.2);
    assertEquals("somevaluehere", out.toString());
}

答案 3 :(得分:1)

这可能是重构类的一个很好的例子 - 如果可能的话,你可能没有这样做的范围 - 使其更易于测试。例如。如果你的方法返回一个String,你可以更好地测试它。因此,一种选择可能是创建两种方法:

  • generateDisplayString()
  • displayForecast(String displayMe)

或者,让displayForecast()调用generateDisplayString()本身。您可以使用一些模型来使您的课程更易于测试。

答案 4 :(得分:0)

我建议您为私有方法创建gettters和setter(如果您正在使用Eclipse:右键单击您的类并选择source,创建getter和setter并单击“select all”)。然后,您可以使用这些方法来查看您的私有变量是否已更改。

@Test
public void testUpdate1() {
    //create a new instance of ForecastDisplay, for example fcd
    ...
    fcd.update(29, 45, 35);
    assertEquals(fcd.getCurrentPressure, 35, 0);
}

答案 5 :(得分:0)

即使您无法重构显示,也要为当前压力添加一个吸气剂,并在测试中使用它来确定它是否设置正确。