英文:
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<Double> 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("./Src/Chapter3/grade.txt"));
System.out.printf("The average grade is: %.2f", 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(() -> 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<Double> 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("./Src/Chapter3/grade.txt"));
System.out.printf("The average grade is: %.2f", 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(() -> 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.
Example of how you can modify your test
@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);
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论