Проблема с сохранением выходного потока - PullRequest
0 голосов
/ 08 июня 2019

При тестировании Java-программы с консольными входами я создал ByteArrayOutputStream и установил его в качестве системы для тестирования. Первый тест выполнен правильно, а выходные и входные потоки выглядят хорошо. Однако при выполнении второго теста входной поток записывается неправильно, и я не уверен, почему.

Я пробовал сбрасывать и закрывать выходные потоки в конструкторах классов и деструкторах. Пустые инициализирующие входные потоки.

Главная * * 1005

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 Ответ

1 голос
/ 08 июня 2019

Ваша проблема здесь:

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

В своем тесте вы создаете новый Reader с имитацией ввода и заменяете System.in им. Проблема в том, что этот статический элемент создается только один раз и не заменяется новым макетом. Это заставляет его возвращать ноль при последующих чтениях, по умолчанию равным 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();
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...