输出流持久性问题



在使用控制台输入测试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, equilateralnor 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 = "3rn3rn3";
        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 = "3rn4rn2";
        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:预期:结果为:斯卡因实际:结果为:等边

你的问题在这里:

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

在测试中,您将创建一个具有模拟输入的新阅读器,并用它替换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, equilateralnor 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 = "3rn3rn3";
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 = "3rn3rn3";
ByteArrayInputStream in = new ByteArrayInputStream(mockinput.getBytes());
new TriTyp(new BufferedReader(new InputStreamReader(in))).run();

最新更新