输出流持久性问题

时间:2019-06-08 04:38:26

标签: java junit

在使用控制台输入测试Java程序时,我创建了一个ByteArrayOutputStream并将其设置为用于测试的系统。第一次测试正确执行,输出和输入流看起来不错。但是,当第二个测试执行时,输入流无法正确捕获,我不确定为什么。

我尝试在类构造函数和析构函数中刷新和关闭输出流。空初始化输入流。

主要

import java.io.*;

public class TriTyp {
   private static String[] triTypes = { "", // Ignore 0.
      "scalene", "isosceles", "equilateral", "not a valid triangle"};
   private static String instructions = "This is the ancient TriTyp program.\nEnter three integers that represent the lengths of the sides of a triangle.\nThe triangle will be categorized as either scalene, isosceles, equilateral\nor invalid.\n";
   public static BufferedReader in = new BufferedReader(new InputStreamReader(System.in));

public static void main (String[] argv)
{  // Driver program for TriTyp
   int A, B, C;
   int T;

   System.out.println (instructions);
   System.out.println ("Enter side 1: ");
   A = getN();
   System.out.println ("Enter side 2: ");
   B = getN();
   System.out.println ("Enter side 3: ");
   C = getN();
   T = triang (A, B, C);

   System.out.println ("Result is: " + triTypes[T]);
}

private static int triang (int Side1, int Side2, int Side3)
{
   if (Side1 <= 0 || Side2 <= 0 || Side3 <= 0)
   {
      triOut = 4;
      return (triOut);
   }

   triOut = 0;
   if (Side1 == Side2)
      triOut = triOut + 1;
   if (Side1 == Side3)
      triOut = triOut + 2;
   if (Side2 == Side3)
      triOut = triOut + 3;
   if (triOut == 0)
   {
     if (Side1+Side2 <= Side3 || Side2+Side3 <= Side1 ||
        Side1+Side3 <= Side2)
        triOut = 4;
     else
        triOut = 1;
     return (triOut);
   }

   if (triOut > 3)
      triOut = 3;
   else if (triOut == 1 && Side1+Side2 > Side3)
      triOut = 2;
   else if (triOut == 2 && Side1+Side3 > Side2)
      triOut = 2;
   else if (triOut == 3 && Side2+Side3 > Side1)
      triOut = 2;
   else
      triOut = 4;
   return (triOut);
}

private static int getN ()
{
   int inputInt = 1;
   String inStr;

   try
   {
      inStr    = in.readLine ();
      inputInt = Integer.parseInt(inStr);
   }
   catch (IOException e)
   {
      System.out.println ("Could not read input, choosing 1.");
   }
   catch (NumberFormatException e)
   {
      System.out.println ("Entry must be a number, choosing 1.");
   }

   return (inputInt);
}
}

测试

import java.io.*;
import java.util.Arrays;
import static org.junit.Assert.*;
import org.junit.*;
import java.nio.charset.StandardCharsets;
import java.io.ByteArrayOutputStream;
import java.io.PrintStream;

public class TriTypTest {
    private PrintStream originalOut = System.out;
    private PrintStream originalErr = System.err;
    private InputStream originalIn = System.in;

    private ByteArrayOutputStream outContent = new ByteArrayOutputStream();

    @Before
    public void setUp() throws Exception {
        outContent = new ByteArrayOutputStream();
        System.setOut(new PrintStream(outContent));
    }

    @After
    public void tearDown() throws Exception {
        System.out.flush();
        System.setOut(originalOut);
    }

    @Test
    public void TestEquilateral() {
        // Set up input of an equilateral triangle for TriTyp.main()
        // String mockinput = "3" + System.lineSeparator() + "3" + System.lineSeparator() + "3";
        String mockinput = "3\r\n3\r\n3";
        ByteArrayInputStream in = new ByteArrayInputStream(mockinput.getBytes());
        // Set up mock user input stream
        System.setIn(in);

        // Initialize the TriTyp.main(input) method
        String[] mainin = {};
        TriTyp.main(mainin);

        // Capture the standard output
        String triout = outContent.toString();
        String[] chopout = triout.split(System.lineSeparator());
        String triangletype = chopout[chopout.length - 1];

        // Call assert for equilateral triangle output
        assertEquals("Result is: equilateral",triangletype);
    }

    @Test
    public void TestScalene() throws Exception {
        // Set up input of an equilateral triangle for TriTyp.main()
        String mockinput = "3\r\n4\r\n2";
        ByteArrayInputStream in = new ByteArrayInputStream(mockinput.getBytes());
        // Set up mock user input stream
        System.setIn(in);

        // Initialize the TriTyp.main(input) method
        String[] mainin = {};
        TriTyp.main(mainin);

        // Capture the standard output
        String triout = outContent.toString();
        String[] chopout = triout.split(System.lineSeparator());
        String triangletype = chopout[chopout.length - 1];

        // Call assert for equilateral triangle output
        assertEquals("Result is: scalene", triangletype);
    }
}

上次测试断言失败:

org.junit.ComparisonFailure: 预期结果为:斜角 实际:结果是:等边

1 个答案:

答案 0 :(得分:1)

您的问题在这里:

public static BufferedReader in = new BufferedReader(new InputStreamReader(System.in));

在测试中,您将使用模拟输入创建一个新的Reader,并将其替换为System.in。问题在于,此静态成员仅创建一次,而不会被新的模拟代替。这会导致它在后续读取时返回null,默认为1,从而导致输出错误。

我建议的解决方法是放下静电,注入阅读器,以便可以替换它,并且仅将main用作合成根。

public class TriTyp {
    private static String[] triTypes = {"", // Ignore 0.
        "scalene", "isosceles", "equilateral", "not a valid triangle"};
    private static String instructions = "This is the ancient TriTyp program.\nEnter three integers that represent the lengths of the sides of a triangle.\nThe triangle will be categorized as either scalene, isosceles, equilateral\nor invalid.\n";

    private final BufferedReader in;

    public TriTyp(BufferedReader in) {
        this.in = in;
    }

    public static void main(String[] argv) {
        new TriTyp(new BufferedReader(new InputStreamReader(System.in))).run();
    }

    public void run() {
        int A, B, C;
        int T;

        System.out.println(instructions);
        System.out.println("Enter side 1: ");
        A = getN();
        System.out.println("Enter side 2: ");
        B = getN();
        System.out.println("Enter side 3: ");
        C = getN();
        T = triang(A, B, C);

        System.out.println("Result is: " + triTypes[T]);
    }

    // Triang and getN methods. Just drop their static keyword.
}

在测试中,您将替换为:

String mockinput = "3\r\n3\r\n3";
ByteArrayInputStream in = new ByteArrayInputStream(mockinput.getBytes());
// Set up mock user input stream
System.setIn(in);

// Initialize the TriTyp.main(input) method
String[] mainin = {};
TriTyp.main(mainin);

与此:

String mockinput = "3\r\n3\r\n3";
ByteArrayInputStream in = new ByteArrayInputStream(mockinput.getBytes());
new TriTyp(new BufferedReader(new InputStreamReader(in))).run();