为了好玩(并在课堂上用作教学工具),我正在编写一个类似于 JUnitTests 的程序。我想用它来对高中生编写的代码进行测试。当学生编写使用扫描仪通过 System.in 获取用户输入的代码时,我想“劫持”扫描仪以提供我自己预先确定的用户输入。除了我希望我的扫描仪成为自动测试仪的内部类之外,我一切都工作得很好。下面的例子过于简单化了,但是很能说明问题。假设一个学生写了这样的代码:import java.util.*;public class Practice { public static void practiceScanners() { Scanner console = new Scanner(System.in); System.out.print("Type first name, age, and address >> "); String name = console.next(); int age = console.nextInt(); String address = console.nextLine(); System.out.println(name + " is " + age + " and lives at" + address + "."); }}然后,假设我有一个名为 AutoTester 的类,它看起来像这样的伪代码:public class AutoTester { public main() { * use JavaCompiler from ToolProvider to compile Practice.java * use reflection to invoke Practice.practiceScanners() * (hopefully) have student code use my Scanner instead of java.util.Scanner * collect output of running the student code * compare against expected output } //My version of Scanner is an inner class within AutoTester public class Scanner { private String script = "Bob 13 42 Maple Drive"; <* implementation not shown *> }}如果我将我的 Scanner 版本移至其自己的 Scanner.java 文件中,则效果很好。学生代码在查看 java.util 之前使用我的(本地)扫描仪。但是,当我将扫描仪作为内部类移动到自动测试器中时,学生代码不知道在那里寻找它。我不想以任何方式编辑学生代码(例如更改扫描仪实例化行以表示新的 AutoTester.Scanner(System.in))在编译/运行学生的程序而不对其代码进行任何编辑时,有什么方法可以使我的 AutoTester.Scanner 优先于 java.util.Scanner 吗?
1 回答
湖上湖
TA贡献2003条经验 获得超2个赞
不幸的是,事实并非如此。自定义扫描仪的类名实际上是AutoTester.Scanner
,您在测试类中定义了它,除了看起来相似的名称之外,它与 java.util.Scanner 无关。Practice
所以这根本不影响。
您必须重构Practice
代码才能使用@Inject
s (例如使用CDI)作为扫描仪。然后使用mockito(@Mock,@InjectMocks)连接您的扫描仪。不过,这是很多重型机械。作为替代方案,您可以设计Practice
为将 Scanner 作为构造函数参数或属性。
但仍然存在问题,即 Scanner 是无法扩展的最终类。因此,您必须为此目的引入自己的接口,在一种情况下将 java.util.Scanner 放在引擎盖下,在另一种情况下将您的替代扫描仪放在引擎盖下。
添加回答
举报
0/150
提交
取消