Junit测试用于扫描仪参数文件阅读器。

huangapple go评论47阅读模式
英文:

Junit test for scanner parameter filereader

问题

I will only provide translations for the non-code parts of your text:

"What I am trying to do is to simply write a test for the calcGrade(scanner sc) function, but I don't know if it's possible to test it in this scenario since the scanner reads in grades in a textfile then returns an average of them."

我试图做的是简单地为calcGrade(scanner sc)函数编写一个测试,但我不知道在这种情况下是否可以测试它,因为扫描器从文本文件中读取成绩然后返回它们的平均值。

"grade.txt"

grade.txt

英文:

What I am trying to do is to simply write a test for the calcGrade(scanner sc) function, but I don't know if it's possible to test it in this scenario since the scanner reads in grades in a textfile then returns an average of them.

public static void main(String[] args) throws FileNotFoundException {
        
        Scanner sc = new Scanner(new FileReader("./Src/Chapter3/grade.txt"));
        
        System.out.printf("The average grade is: %.2f", calcGrade(sc));
                
    }

    public static double calcGrade(Scanner sc) {
        double test1, test2, test3, test4, test5, avg;

        test1 = sc.nextDouble();
        test2 = sc.nextDouble();
        test3 = sc.nextDouble();
        test4 = sc.nextDouble();
        test5 = sc.nextDouble();
        avg = (test1 + test2 + test3 + test4 + test5) / 5.0;
        
        sc.close();
        return avg;
    }

 @Test

    public void testCalGrade() {
    double expected = 70.0;
    double actual = js.calcGrade(); //i could change the parameter here instead passed in scanner to the individual grades then test it
    assertEquals(expected, actual,0.02);
}

grade.txt

80 98 100 78 65.6

答案1

得分: 0

由于Scanner是一个最终类,您无法在测试中提供模拟(或任何虚假对象)来代替使用真实的Scanner对象。

理论上,您仍然可以使用外部库(如PowerMock)创建模拟对象或更改System.in字段,但更好的方法是使calcGrade方法更加通用。例如,它可以接受Supplier<Double>而不是Scanner。这是一个示例。

public static double calcGrade(Supplier&lt;Double&gt; valueSupplier) {
    double test1, test2, test3, test4, test5, avg;

    test1 = valueSupplier.get();
    test2 = valueSupplier.get();
    test3 = valueSupplier.get();
    test4 = valueSupplier.get();
    test5 = valueSupplier.get();
    avg = (test1 + test2 + test3 + test4 + test5) / 5.0;

    return avg;
}

然后您可以这样调用它

public static void main(String[] args) throws FileNotFoundException {

    Scanner sc = new Scanner(new FileReader(&quot;./Src/Chapter3/grade.txt&quot;));

    System.out.printf(&quot;The average grade is: %.2f&quot;, calcGrade(sc::nextDouble));
    sc.close();
}

如果您不了解sc::nextDouble语法,它被称为方法引用,当调用valueSupplier.get()时,它基本上调用sc.nextDouble()

然后,您可以这样测试它

public class CalGradeTest {

    private int index;

    @Test
    public void testCalGrade() {
        CalGrade js = new CalGrade();
        double[] testValues = {68.0, 69.0, 70.0, 71.0, 72.0};
        double expected = 70.0;
        double actual = js.calcGrade(() -&gt; testValues[index++]);
        assertEquals(expected, actual, 0.02);
    }
}
英文:

Since Scanner is a final class, you cannot provide a mock (or any fake object) instead of using a real Scanner object in the test.

Though theoretically you still could create a mock using external libraries (like PowerMock) or change the System.in field, a better way would be to make the calcGrade method more generic.
E.g. it could accept a Supplier<Double> instead of a Scanner. Here is an example.

    public static double calcGrade(Supplier&lt;Double&gt; valueSupplier) {
        double test1, test2, test3, test4, test5, avg;

        test1 = valueSupplier.get();
        test2 = valueSupplier.get();
        test3 = valueSupplier.get();
        test4 = valueSupplier.get();
        test5 = valueSupplier.get();
        avg = (test1 + test2 + test3 + test4 + test5) / 5.0;

        return avg;
    }

Then you can call it like this

    public static void main(String[] args) throws FileNotFoundException {

        Scanner sc = new Scanner(new FileReader(&quot;./Src/Chapter3/grade.txt&quot;));

        System.out.printf(&quot;The average grade is: %.2f&quot;, calcGrade(sc::nextDouble));
        sc.close();
    }

If you don't know the sc::nextDouble Syntax, it's called a method reference and basically calls sc.nextDouble() when valueSupplier.get() is called.

Then you could test it like this

public class CalGradeTest {

    private int index;

    @Test
    public void testCalGrade() {
        CalGrade js = new CalGrade();
        double[] testValues = {68.0, 69.0, 70.0, 71.0, 72.0};
        double expected = 70.0;
        double actual = js.calcGrade(() -&gt; testValues[index++]);
        assertEquals(expected, actual, 0.02);
    }
}

答案2

得分: 0

Here's the translated content:

扫描器有多个构造函数,因此您可以选择一个不同的构造函数并使用它。

查看可能的构造函数

以下是您如何修改测试的示例

@Test
public void testCalGrade() {
   double expected = 70.0;
   double actual = js.calcGrade(new Scanner("80 98 100 78 65.6"));
   assertEquals(expected, actual, 0.02);
}
英文:

Scanner has multiple constructors, so you can choose a different one and use that.

See the possible constructors

Example of how you can modify your test

 @Test
 public void testCalGrade() {
    double expected = 70.0;
    double actual = js.calcGrade(new Scanner(&quot;80 98 100 78 65.6&quot;));
    assertEquals(expected, actual,0.02);
}

huangapple
  • 本文由 发表于 2020年8月2日 23:53:43
  • 转载请务必保留本文链接:https://go.coder-hub.com/63218079.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定