Что приводит к сбою JUnit и Системных Правил в представлении этого студента?

Я работал над автоматическим грейдером в течение последнего месяца, и один из моих учеников, который понимает, что материал, кажется, постоянно терпит неудачу в моих тестовых случаях JUnit из-за возврата 'null'. Поскольку это курс Java I, они все еще используют System.out.println() в настоящее время. Из-за этого я использую системные правила для анализа их выходных данных.

Студенческое подчинение:

import  java.util.Scanner;

public class DistanceFormula {
     public static void main(String[] args) {

    //Declarations
    double distance;
    double differenceX;
    double differenceY;
    double firstX;
    double secondX;
    double firstY;
    double secondY;

    //User Input for the First X value (X value for Point 1)
    System.out.println("Enter In The value of X for point 1:");
    Scanner inputFirstX = new Scanner(System.in);
    firstX = inputFirstX.nextDouble();

    //User Input for the First Y value  (Y value for Point 1)
    System.out.println("Enter In The value of Y for point 1:");
    Scanner inputFirstY = new Scanner(System.in);
    firstY = inputFirstY.nextDouble();

    //User Input for Second X value (X value for point 2)
    System.out.println("Enter In The value of X for point 2:");
    Scanner inputSecondX = new Scanner(System.in);
    secondX = inputSecondX.nextDouble();

    //User Input for Second Y value (Y value for point 2)
    System.out.println("Enter In The value of Y for point 2:");
    Scanner inputSecondY = new Scanner(System.in);
    secondY = inputSecondY.nextDouble();

    //Find the difference of each point
    differenceX = secondX - firstX;
    differenceY = secondY - firstY;

    //Distance Formula
    distance = Math.sqrt((Math.pow(differenceX, 2)) + (Math.pow(differenceY, 2)));

    //Displaying the outcome
    System.out.println("Your First Point: " + firstX + "," + firstY + "\n" + "Your Second Point: " + 
    secondX + "," + secondY + "\n"  + "The distance between the two points is: " + distance);
     }
}

Один из моих тестовых примеров:

@Rule
public final StandardOutputStreamLog outlog = new StandardOutputStreamLog();

@Rule
public final TextFromStandardInputStream systemInMock = emptyStandardInputStream();
...
@Test(timeout=5000)
public void tests1() {
    double x1 = 5.0;
    double y1 = 5.0;
    double x2 = 4.5;
    double y2 = 4.5;
    systemInMock.provideText(x1+"\n"+y1+"\n"+x2+"\n"+y2+"\n");
    TestFile.main(new String[]{});
    String reality = outlog.getLog().toLowerCase();
    double calc = distance(x1,y1,x2,y2);
    boolean result = reality.contains(calc+"");
    assertTrue("Testing "+x1+" "+y1+" "+x2+" "+y2+" ", result);
}

Наконец, мой TestRunner:

// JUnit
import org.junit.runner.JUnitCore;
import org.junit.runner.Result;
import org.junit.runner.notification.Failure;

// SimpleJSON
import org.json.simple.JSONObject;
import org.json.simple.JSONArray;

public class TestRunner {
    @SuppressWarnings("unchecked")
    public static void main(String[] args) {
        JSONObject obj = new JSONObject();
        Result result = JUnitCore.runClasses(TestJunit.class);

        double tests = result.getRunCount();
        double fails = result.getFailureCount();
        obj.put("tests", tests);
        obj.put("fails", fails);

        //System.out.println("Testing Complete\n---------------------------");
        //System.out.printf("Run Time of Tests:\t%d ms\n", result.getRunTime());
        //System.out.printf("Number of Tests:\t%d\n", (int)tests);

        if (result.wasSuccessful()){
            //System.out.println("All Tests Successful");
        } else {
            //System.out.println("Test Fails\n---------------------------");
            JSONArray failures = new JSONArray();
            System.out.printf("Number of Fails:\t%d\n", (int)fails);
            for (Failure failure : result.getFailures()) {
                String header = failure.getTestHeader();
                String msg = failure.getMessage();
                if (msg.contains("timed out")){
                    failures.add(header + " " + msg);
                    System.out.println(header + " " + msg);
                } else {
                    failures.add(msg);
                    System.out.println(msg);
                }
                obj.put("failures", failures);
            }
        }

        //System.out.println("Results\n---------------------------");
        double grade = 100.0 * (double)((tests - fails)/tests);
        obj.put("grade", grade);
        System.out.printf("Grade:\t\t\t%.1f%%\n", grade);
        System.out.print("JSON:\n");
        System.out.println(obj);
    }
} 

В TestRunner if (msg.contains("timed out")) будет ошибка, потому что сообщение null,

Если я запускаю код студента или проверяю чужую работу, тесты выполняются отлично. Если это что-то на моем конце, я бы хотел это исправить. Спасибо!

2 ответа

Решение

Проблема исправлена ​​в Системных правилах 1.11.0. Вы должны предоставить несколько строк:

systemInMock.provideLines(
  Double.toString(x1),
  Double.toString(y1),
  Double.toString(x2),
  Double.toString(y2));

Scanner буферизуется, поэтому каждый созданный экземпляр потребляет больше текста из макета System.in чем то, что нужно для nextDouble, Следующий Scanner пытается прочитать то, что осталось от того же основного потока, но вход уже использовался так nextDouble бросает NoSuchElementException,

Вы могли бы попытаться более точно издеваться System.in возвращая меньшее количество байтов (но не указывая конец потока) до следующего вызова System.out обнаружено, или измените подход и использование Runtime.exec создать новую JVM и захватить весь вывод этого процесса.

Другие вопросы по тегам