為了好玩(并在課堂上用作教學工具),我正在編寫一個類似于 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
提交
取消