為了好玩(并在課堂上用作教學(xué)工具),我正在編寫一個(gè)類似于 JUnitTests 的程序。我想用它來對(duì)高中生編寫的代碼進(jìn)行測試。當(dāng)學(xué)生編寫使用掃描儀通過 System.in 獲取用戶輸入的代碼時(shí),我想“劫持”掃描儀以提供我自己預(yù)先確定的用戶輸入。除了我希望我的掃描儀成為自動(dòng)測試儀的內(nèi)部類之外,我一切都工作得很好。下面的例子過于簡單化了,但是很能說明問題。假設(shè)一個(gè)學(xué)生寫了這樣的代碼: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 + "."); }}然后,假設(shè)我有一個(gè)名為 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 文件中,則效果很好。學(xué)生代碼在查看 java.util 之前使用我的(本地)掃描儀。但是,當(dāng)我將掃描儀作為內(nèi)部類移動(dòng)到自動(dòng)測試器中時(shí),學(xué)生代碼不知道在那里尋找它。我不想以任何方式編輯學(xué)生代碼(例如更改掃描儀實(shí)例化行以表示新的 AutoTester.Scanner(System.in))在編譯/運(yùn)行學(xué)生的程序而不對(duì)其代碼進(jìn)行任何編輯時(shí),有什么方法可以使我的 AutoTester.Scanner 優(yōu)先于 java.util.Scanner 嗎?
1 回答

湖上湖
TA貢獻(xiàn)2003條經(jīng)驗(yàn) 獲得超2個(gè)贊
不幸的是,事實(shí)并非如此。自定義掃描儀的類名實(shí)際上是AutoTester.Scanner
,您在測試類中定義了它,除了看起來相似的名稱之外,它與 java.util.Scanner 無關(guān)。Practice
所以這根本不影響。
您必須重構(gòu)Practice
代碼才能使用@Inject
s (例如使用CDI)作為掃描儀。然后使用mockito(@Mock,@InjectMocks)連接您的掃描儀。不過,這是很多重型機(jī)械。作為替代方案,您可以設(shè)計(jì)Practice
為將 Scanner 作為構(gòu)造函數(shù)參數(shù)或?qū)傩浴?/p>
但仍然存在問題,即 Scanner 是無法擴(kuò)展的最終類。因此,您必須為此目的引入自己的接口,在一種情況下將 java.util.Scanner 放在引擎蓋下,在另一種情況下將您的替代掃描儀放在引擎蓋下。
添加回答
舉報(bào)
0/150
提交
取消