JUnit 测试含有控制台输入的方法
使用JUnit 進行單元測試時,有時會遇到被測試方法存在控制臺輸入的情況,這樣在測試時需要不厭其煩地手動輸入測試用例,顯然違背了自動測試的初衷。
本文簡介兩種通過輸入重定向實現自動測試控制臺輸入的方法。
代碼:https://github.com/1161140118/TEST-code/tree/master/src/KeyBoardInputTransform
?
下面是待測試類ReadFromConsole,其中的ReadAndShow為我們要測試的含有控制臺輸入的方法。
1 public class ReadFromConsole { 2 private Scanner in = new Scanner(System.in); 3 4 public void setIn(ByteArrayInputStream baIn) { 5 this.in = new Scanner(baIn); 6 } 7 8 public void ReadAndShow() { 9 String line = in.nextLine(); 10 System.out.println("This is the input: \n"+line); 11 } 12 13 public static void main(String[] args) { 14 ReadFromConsole r = new ReadFromConsole(); 15 r.ReadAndShow(); 16 } 17 18 }?
首先簡單了解下輸入重定向 System.setIn() 方法
Java.lang.System.setIn() 方法重新分配標準輸入流
?
/** * 函數聲明* @param in - 新的標準輸入流*/ public static void setIn(InputStream in);?
?
示例
1 private static ByteArrayInputStream in; 2 private static Scanner scanner; 3 4 public static void input() { 5 String data = "Hello, World!"; 6 InputStream stdin = System.in; 7 try { 8 // 輸入重定向 9 System.setIn(new ByteArrayInputStream(data.getBytes())); 10 // 此時 System.in 為ByteArrayInputStream對象 11 scanner = new Scanner(System.in); 12 System.out.println(scanner.nextLine()); 13 } finally { 14 System.setIn(stdin); 15 } 16 }調用input方法,輸出
Hello, World!本次調用沒有要求從控制臺輸入語句,直接輸出data字符串。
?
?
言歸正傳 討論我們的解決問題方法:
?
方案1 當被調用類存在Scanner對象時,可臨時創建相關方法使得類內輸入被重定向為指定字符串的字節流,如下
?
public class ReadFromConsole {private Scanner in = new Scanner(System.in);/*** 獲得測試所需標準輸入字符串,作為Scanner對象讀取源* @param baIn - 測試所需標準輸入字符串的字節流,由測試類傳入*/public void setIn(ByteArrayInputStream baIn) {// 更改類內 in 的讀取對象為 輸入字節流 baInthis.in = new Scanner(baIn);}?
需要注意的時,該方法需要在類示例之后,具體方法被調用測試之前調用,即在開始測試待測試方法前設置好輸入字節流。
public void ReadAndShow() {String line = in.nextLine();System.out.println("This is the input: \n"+line);}public static void main(String[] args) {ReadFromConsole r = new ReadFromConsole();// 輸入字符串中的 \n 換行符將被 Scanner.nextline()方法識別ByteArrayInputStream in1 = new ByteArrayInputStream("1\n2".getBytes());r.setIn(in1);r.ReadAndShow();r.ReadAndShow();// 重新調用setIn方法以重新設置分配字符串ByteArrayInputStream in2 = new ByteArrayInputStream("3".getBytes());r.setIn(in2);r.ReadAndShow();}輸出結果:
This is the input: 1 This is the input: 2 This is the input: 3?
優點為可以在測試不同方法時靈活設置輸入流的具體內容;
缺點為需要在被測試類內新增輸入流設置方法,在測試完成后需要刪除該方法并修改Scanner對象的限制符。
?
方案2
直接在測試類內重定向輸入流,間接改變被調用函數輸入流
private static ByteArrayInputStream in;/** 2.直接重定向輸入流* System.setIn((ByteArrayInputStream in);* 即通過重定向,間接改變輸入流*//*** 設置輸入字符串作為輸入流* @param input - 測試所需輸入字符串*/public void setInput(String input) {in = new ByteArrayInputStream(input.getBytes());System.setIn(in);}@Testpublic void testReadFromConsole() {// 換行符\n 以匹配多次 Scanner.nextline() String inputMessage = "one\n"+ "two\n"+ "three\n" + "four\n"+ "five\n"+ "";// 僅設置一次輸入流 setInput(inputMessage);// 直接調用需從控制臺輸入的方法,不需要調用待測類中的輸入流設置方法ReadFromConsole r = new ReadFromConsole();r.ReadAndShow();r.ReadAndShow();r.ReadAndShow();r.ReadAndShow();r.ReadAndShow();}測試結果:
This is the input: one This is the input: two This is the input: three This is the input: four This is the input: five優點為不需要修改測試函數,直接在測試類中重定向標準輸入流,待測類受到影響;
缺點為必須在待測類實例化后測試開始前一次性初始化所有輸入字符串,以\n為分隔,在后續測試方法時不能在調用重定向標準輸入流,否則會拋出異常。
?
轉載于:https://www.cnblogs.com/standingby/p/9033399.html
總結
以上是生活随笔為你收集整理的JUnit 测试含有控制台输入的方法的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 算法系列之五 希尔排序
- 下一篇: linux 定时任务