s71200模拟量输入输出_模拟用户输入并检查输出的简单方法
s71200模擬量輸入輸出
最近,我的一些學生向我詢問了赫爾辛基大學MOOC提供的單元測試的機制,我檢查了它們的實現(xiàn),并認為這對于初學者了解實際發(fā)生的情況是有幫助的,因此在此發(fā)表了這篇小文章。
我們將以“機場”項目為例,這是OOP2第一周的最后一項任務(wù)。
我們僅關(guān)注測試,因此我將跳過有關(guān)如何解決它的事情。 在本練習中,我們將每次手動執(zhí)行main方法,重復輸入飛機編號,容量,有時我們認為我們的代碼可以使用,然后運行本地測試,以便我們可以提交給服務(wù)器進行在線判斷和評分。
我一直使用這個小項目作為借助單元測試保護的重構(gòu)示例。 當我又重復又痛苦地輸入飛機ID,容量編號,機場代碼和操作代碼時,我問我的學生:“這很痛苦嗎?”。
顯然,他們所有人都回答了。 然后我問,“即使無聊又痛苦,您會一次又一次地進行這種測試嗎?”
安靜。
從我過去的經(jīng)驗中,我知道跳過這些無聊的測試很容易,并且我們可以安慰自己,“這些代碼非常簡單,我不會犯錯,它將起作用,并且會起作用,不用擔心。”
由于做出這樣的選擇,我會留下痛苦的回憶,因為過去我犯了太多簡單而愚蠢的錯誤,所以無論看起來多么簡單,我仍然會進行測試-即使是手動測試,也無聊而痛苦。
我添加此內(nèi)容是因為單元測試無法完全替代手動測試,盡管它將使手動測試更加容易和有效。
對于Airport項目,如果不需要每次都重復輸入,并且可以捕獲程序的輸出,則與預期相比,我們將更快地獲得反饋。
String operation = scanner.nextLine(); ... System.out.println("Blahblahblah...");例如,我們確切地知道是否首先輸入x ,然后它將進入飛行服務(wù)部分并打印菜單選項,如果我們第二次輸入x ,則程序?qū)⒔Y(jié)束循環(huán)并退出,結(jié)果,我們將僅獲取機場面板和飛行服務(wù)的說明輸出。
因此,讓我們轉(zhuǎn)到一個測試案例,看看實際會發(fā)生什么。
@Test public void printsMenusAndExits() throws Throwable {String syote = "x\nx\n";MockInOut io = new MockInOut(syote);suorita(f(syote));String[] menuRivit = {"Airport panel","[1] Add airplane","[2] Add flight","[x] Exit","Flight service","[1] Print planes","[2] Print flights","[3] Print plane info","[x] Quit"};String output = io.getOutput();String op = output;for (String menuRivi : menuRivit) {int ind = op.indexOf(menuRivi);assertRight(menuRivi, syote, output, ind > -1);op = op.substring(ind + 1);} }上面是第二個測試用例,它涵蓋了我們所說的最簡單的情況,僅輸入兩個x 。
當我們查看測試代碼時,它分為三部分:
- 準備輸入
- 執(zhí)行Main.main(args)方法
- 檢查輸出以查看它是否依次包含所有預期行
您知道scanner.nextLine()或scanner.nextInt()的正常行為。 該程序?qū)炱鸩⒌却脩糨斎?#xff0c;以便執(zhí)行下一行代碼。 但是,為什么它在沒有任何等待的情況下可以平穩(wěn)運行?
在轉(zhuǎn)到本部分之前,我想簡要解釋一下該方法的執(zhí)行,它使用Java反射以一種不直接但可以進行更多檢查的方式來調(diào)用該方法,例如,第一個測試用例要求Main為公共類,但您可能會發(fā)現(xiàn)要通過手動測試,可以將Main訪問級別設(shè)置為package。
@Test public void classIsPublic() {assertTrue("Class " + klassName + " should be public, so it must be defined as\n" +"public class " + klassName + " {...\n}", klass.isPublic()); }在這里, klass.isPublic()正在檢查是否根據(jù)需要設(shè)置訪問級別。
好。 看起來MockInOut類使魔術(shù)發(fā)生了,我們可以檢查代碼以在MockInOut找到想法。 您可以在GitHub上訪問源代碼。
public MockInOut(String input) {orig = System.out;irig = System.in;os = new ByteArrayOutputStream();try {System.setOut(new PrintStream(os, false, charset.name()));} catch (UnsupportedEncodingException ex) {throw new RuntimeException(ex);}is = new ByteArrayInputStream(input.getBytes());System.setIn(is); }您可能已經(jīng)輸入System.out數(shù)千次了,但是您是否意識到可以像上面一樣默默地更改out ? 這同時設(shè)置out與in系統(tǒng)的,這樣我們就可以完全執(zhí)行后得到的輸出,我們也不需要手工輸入這個時候,因為在聲明Scanner scanner = new Scanner(System.in); ,則參數(shù)System.in會以無提示方式更改,因此scanner.nextLine()將獲得準備好的輸入而不會掛起。
同樣,輸出將不會在控制臺中打印,而是會累積到ByteArrayOutputStream ,此后可以訪問。
您可能想知道,如果我們真的想恢復System.in和System.out的正常行為,該怎么辦?
/*** Restores System.in and System.out*/ public void close() {os = null;is = null;System.setOut(orig);System.setIn(irig); }基本上,它節(jié)省了原來in和out ,需要恢復時,只需再次清除遭入侵的人,并設(shè)置他們回來,那么一切都將照常進行。
您可以在下面復制簡單的示例代碼以進行快速測試。
import java.io.*; import java.util.*;class HelloWorld {public static void main(String[] args) throws IOException {PrintStream orig = System.out;ByteArrayOutputStream os = new ByteArrayOutputStream();System.setOut(new PrintStream(os, false, "UTF-8"));// Here it won't print but just accumulatefor (int i = 0; i < 100; i++) {System.out.println("Hello World");}System.setOut(orig);// Print 100 lines of "Hello World" here since out was restoredSystem.out.println(os.toString("UTF-8"));InputStream is = System.in;System.setIn(new ByteArrayInputStream("x\nx\n".getBytes()));Scanner scanner = new Scanner(System.in);// Without hang onSystem.out.println(scanner.nextLine());System.out.println(scanner.nextLine());try {// There are only two lines provided, so here will failSystem.out.println(scanner.nextLine());} catch (NoSuchElementException e) {e.printStackTrace();}System.setIn(is);scanner = new Scanner(System.in);// Hang on here since `in` was restoredSystem.out.println(scanner.nextLine());} }實際上,注入和替換是一種使單元測試的依賴關(guān)系解耦的常用方法,這對于僅關(guān)注代碼非常有用。 還有更先進,更復雜的方法來做到這一點,但在這里,我們只是想說明一個簡單的方法是“黑客” in和out ,這樣你可以專注于你的代碼,而不是in與out 。
對于某些遺留項目,此方法可能對重構(gòu)至關(guān)重要,因為太多的依賴關(guān)系使測試變得非常困難!
翻譯自: https://www.javacodegeeks.com/2019/02/approach-simulate-input-check-output.html
s71200模擬量輸入輸出
總結(jié)
以上是生活随笔為你收集整理的s71200模拟量输入输出_模拟用户输入并检查输出的简单方法的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 全球ddos实时监控(全球ddos监控图
- 下一篇: 安卓命令大全下载(安卓命令大全)