模拟用户输入并检查输出的简单方法

最近,我的一些学生向我询问了赫尔辛基大学MOOC提供的单元测试的机制,我检查了它们的实现,并认为这对于初学者了解实际发生的情况是有帮助的,因此在此发表了这篇小文章。

我们将以“机场”项目为例,这是OOP2第一周的最后一项任务。

我们仅关注测试,因此我将跳过有关如何解决它的事情。 在本练习中,我们将每次手动执行main方法,重复输入飞机编号,容量,有时我们认为我们的代码可以工作,然后运行本地测试,以便可以提交给服务器进行在线判断和评分。

用户输入

我一直使用这个小项目作为借助单元测试保护的重构示例。 当我又重复又痛苦地输入飞机ID,航班号,机场代码和操作代码时,我问我的学生:“这很痛苦吗?”。

显然,他们所有人都回答了。 然后我问,“即使无聊又痛苦,您会一次又一次地进行这种测试吗?”

安静。

从我过去的经验中,我知道跳过这些无聊的测试很容易,并且我们可以安慰自己,“这些代码非常简单,我不会犯错,它将起作用并且会起作用,不用担心。”

由于做出这样的选择,我会留下痛苦的回忆,因为过去我犯了太多简单而愚蠢的错误,所以无论看起来多么简单,我仍然会进行测试-即使是手动测试,也无聊而痛苦。

我添加此内容是因为单元测试无法完全替代手动测试,尽管它将使手动测试更加容易和有效。

对于Airport项目,如果不需要每次都重复输入,并且可以捕获程序的输出,则与预期相比,我们将更快地获得反馈。

String operation = scanner.nextLine();
...
System.out.println("Blahblahblah...");

例如,我们确切地知道是否首先输入x ,然后它将进入飞行服务部分并打印菜单选项;如果我们第二次输入x ,则程序将结束循环并退出,结果,我们将仅获取机场面板和飞行服务的说明输出。

因此,让我们转到一个测试用例,看看实际会发生什么。

@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

当我们查看测试代码时,它分为三部分:

  • 准备输入
  • 执行Main.main(args)方法
  • 检查输出以查看它是否依次包含所有预期行

您知道scanner.nextLine()scanner.nextInt()的正常行为。 该程序将挂起并等待用户输入,以便执行下一行代码。 但是,为什么它在这里没有任何等待就可以顺利运行?

在开始这一部分之前,我想简要解释一下该方法的执行,它使用Java反射以一种不直接但可以进行更多检查的方式来调用该方法,例如,第一个测试用例要求Main为公共类,但您可能会发现要通过手动测试,可以将Main访问级别设置为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()正在检查是否根据需要设置访问级别。

好。 看来MockInOut类使魔术发生了,我们可以检查代码以在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);
}

您可能已经输入System.out数千次,但是您是否意识到可以像上面一样默默地更改out ? 这同时设置outin系统的,这样我们就可以完全执行后得到的输出,我们也不需要手工输入这个时候,因为在声明Scanner scanner = new Scanner(System.in); ,则参数System.in会以无提示方式更改,因此scanner.nextLine()将获得准备好的输入而不会挂起。

同样,输出将不会在控制台中打印,而是会累积到ByteArrayOutputStream ,此后可以访问。

您可能想知道,如果我们真的要恢复System.inSystem.out的正常行为,该怎么办?

/*** Restores System.in and System.out*/
public void close() {os = null;is = null;System.setOut(orig);System.setIn(irig);
}

基本上,它节省了原来inout ,需要恢复时,只需再次清除遭入侵的人,并设置他们回来,那么一切都将照常进行。

您可以在下面复制简单的示例代码以进行快速测试。

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());}
}

实际上,注入和替换是一种用于分离单元测试依赖关系的常用方法,这对于仅关注代码非常有用。 还有更先进,更复杂的方法来做到这一点,但在这里,我们只是想说明一个简单的方法是“黑客” inout ,这样你可以专注于你的代码,而不是inout

对于某些遗留项目,此方法可能对重构至关重要,因为太多的依赖关系使测试变得非常困难!

翻译自: https://www.javacodegeeks.com/2019/02/approach-simulate-input-check-output.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/344910.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

android bench内存测试,华为p10内存测试软件(androbench) v5.0.1 免费版

华为p10内存测试软件(androbench)其实是androbench这款内存测试软件&#xff0c;可以用于测试你的华为p10&#xff0c;是一款不错的华为p10内存测试软件&#xff0c;可以测试你的手机闪存性能&#xff0c;其他的手机也可以免费测试哦。华为p10内存测试软件介绍AndroBench是衡量…

【渝粤题库】陕西师范大学400011 思想政治教育学科教学论 作业(专升本)

《思想政治学科教学论》作业 一、多选择题 在下列选项中至少有一项是符合题目要求的 &#xff11;、思想政治学科教学论的学科特点包括&#xff1a; A&#xff0e;社会性 B&#xff0e;综合性 C &#xff0e;实践性 D&#xff0e;系统性   E&#xff0e;完整性 &#xff12;、…

【渝粤题库】陕西师范大学700007 生态学

《生态学》作业 一、名词解释 Meta-种群生态系统次生演替边缘效应初级生产量可持续发展岛屿效应主导因子种群空间分布格局营养级物种多样性生态入侵耐性限度生态位光周期现象趋同适应生态恢复同资源种团原生演替协同进化食物链生态平衡繁殖成效内禀增长率 二、简答题简述丹麦学…

android对话框字体大小,Android Dialog 设置字体大小的具体方法

先看下面图片&#xff1a;这是我在做登录页面的时候&#xff0c;调用系统的progressdialog 进行等待&#xff0c;可是看起来很不协调&#xff0c;左边的等待图片过大&#xff0c;右边文字过小&#xff0c;看起来老别扭&#xff0c;虽然功能上不存在什么问题&#xff0c;但是我有…

国家开放大学2021春1062文学英语赏析题目

教育 教育 试卷代号&#xff1a; 1062 2021年春季学期期末统一考试 文学英语赏析 试题 2021年7月 注意事项 一、将你的学号、姓名及分校&#xff08;工作站&#xff09;名称填写在答题纸的规定栏内。考试结束后&#xff0c;把试卷和答题纸放在桌上。试卷和答题纸均不得带出考…

android custom toast,Android自定义Toast

核心代码&#xff1a;package com.huatec.myapplication;import android.content.Context;import android.graphics.Bitmap;import android.support.annotation.ColorInt;import android.support.annotation.DrawableRes;import android.view.Gravity;import android.view.Layo…

【渝粤题库】广东开放大学 大学英语B 形成性考核 (2)

选择题 题目&#xff1a; Do you still get free plastic bags from the supermarkets? Things have changed. China has banned free plastic bags at shops and supermarkets, and people have to pay for using plastic bags. The rule started on June 1. It came becaus…

apache camel_在WildFly中将Apache Camel和Spring添加为jboss模块

apache camel这些天&#xff0c;我在玩Wildfly &#xff0c; Apache Camel和Spring 。 在EAR / WAR之间进行通信的一种简单方法是使用Camel的direct-vm组件。 有或没有骆驼&#xff0c;有很多方法可以实现这一目标。 骆驼在WildFly中就像一个饰物&#xff0c;不需要任何额外的…

国家开放大学2021春1129土木工程力学(本)题目

教育 教育 试卷代号&#xff1a; 1129 2021年春季学期期末统一考试 土木工程力学&#xff08;本&#xff09; 试题 2021年7月 一、单项选择题&#xff08;每小题3分&#xff0c;共30.分。在所列备选项中&#xff0c;选1项正确的或最好的作为答案填入括弧&#xff09; 1.求图示…

华为android打开usb调试模式,华为 PE-CL00 开启USB调试模式

我们要将华为 PE-CL00与电脑进行连接&#xff0c;就必须要打开华为 PE-CL00系统的调试模式&#xff0c;不同的系统版本打开调试模式的方法有所不同&#xff0c;在这里我们就谈谈华为 PE-CL00各种系统版本打开USB调试模式的方法。1、针对Android 2.1-2.2版本的系统&#xff1a;我…

国家开放大学2021春1044合同法题目

教育 教育 试卷代号&#xff1a; 1044 2021年春季学期期末统一考试 合同法 试题 2021年7月 注意事项 一、将你的学号、姓名及分校&#xff08;工作站&#xff09;名称填写在答题纸的规定栏内。考试结束后&#xff0c;把试卷和答题纸放在桌上。试卷和答题纸均不得带出考场。监…

API网关和AWS Lambda进行身份验证

当Foreach最初涉足微服务领域时&#xff0c;我们并没有真正构建微服务。 我们以为我们做到了&#xff0c;但是我们所有的服务中总存在一些逻辑。 当然&#xff0c;每个服务实际上应该只专注于自己的任务&#xff0c;而不应该专注于属于另一个微服务的事物。 我们这方面最明显的…

【渝粤教育】广东开放大学 企业项目报表分析 形成性考核 (35)

题库查询系统 选择题 题目&#xff1a;流动债的流动性分析主要从流动负债的到期日流动负债的推迟可能性两方面进行。 答案&#xff1a; A、正确 题目&#xff1a;营业利润是以主营业务利润为基础加上其他业务利润减去销售费用、管理费用和财务费用,再加上营业外收入减去营业外支…

魅蓝x android 7,魅蓝x2什么时候发布 魅蓝x2发布时间最新消息

日前&#xff0c;魅蓝品牌掌门人李楠或kkk便在微博上放出“bluegate(蓝色大门)”这样一个句子&#xff0c;似乎暗示魅蓝品牌或在近期会有动作&#xff0c;并且由于该条微博的尾巴显示为“下款魅蓝Android”&#xff0c;所以在不少网友看来&#xff0c;或许预示着魅蓝将有新机即…

【渝粤教育】广东开放大学 数据库原理与应用 形成性考核 (1)

题库查询系统 选择题 题目&#xff1a;数据库系统是采用了数据库技术的计算机系统&#xff0c;它是一个集合体&#xff0c;包含数据库、计算机硬件、软件和&#xff08; &#xff09; 答案&#xff1a; A、数据库管理员 题目&#xff1a;数据库&#xff08;DB&#xff09;&am…

Android 21mod,熊猫博士小镇合集 Mod

游戏介绍打通30个独具特色的区域界限&#xff0c;探索并发掘各式各样的奇妙冒险&#xff01;开启乐趣无限的冒险&#xff01;想成为一名维护正义的警察&#xff0c;或经营一间自己的美发沙龙&#xff0c;或成为一名救治动物的兽医&#xff1f;在熊猫博士小镇中&#xff0c;一切…

内存泄漏代码_调查内存泄漏第1部分–编写泄漏代码

内存泄漏代码前几天&#xff0c;我发现了这个小问题&#xff1a;该服务器运行了一段时间&#xff0c;然后掉下来了。 然后通过启动脚本重新启动&#xff0c;整个过程重复进行。 听起来并没有什么坏处&#xff0c;因为它虽然对数据造成了重大损失&#xff0c;但对业务的重要性并…

【渝粤教育】广东开放大学 广东开放大学学习指引 形成性考核 (28)

题库查询系统 选择题 题目&#xff1a;在开放大学的学习中认识同学可以增强开放大学学生间的交流与友情&#xff0c;促进学生对开放大学的归属感与认同感&#xff0c;克服学习中的孤独感。 答案&#xff1a; A、“对”。 题目&#xff1a;广东开放大学服务于广东学习型社会&…

【渝粤教育】广东开放大学 法理学 形成性考核 (46)

题库查询系统 选择题 题目&#xff1a;法理学与部门法的关系是&#xff08; &#xff09;的关系。 答案&#xff1a; A、理论与实际 B、 一般与特殊 C、 整体与局部 D、论与史 题目&#xff1a;法的最终决定因素是&#xff08;&#xff09;。 答案&#xff1a; A、阶级斗争状况…

android 打印kernel log,android8.0 kernel4.9.44 各层log打开

一.问题平台android8.0 kernel4.9.44&#xff0c;想加个i2c驱动&#xff0c;打开log都是一件脑瓜疼的事。二.log总结android有三种log。1.kernel下面的&#xff0c;就是driver层log。2.kernel上面的&#xff0c;init和init.rc启动的程序的log&#xff0c;应用层3.kernel上面的&…