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

s71200模拟量输入输出

最近,我的一些学生向我询问了赫尔辛基大学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

s71200模拟量输入输出

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

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

相关文章

mysql设计一个简单的系统_一个简单数据库设计例子

一个曾经做过的简单的管理系统中数据库设计的例子,包括设计表、ER图、建模、脚本. 项目信息 Project Name: Book Manager System DB: MySQL5.5 DB Name: db_library Tables: 1). tb_book_info 2). tb_user 3). tb_admin_info 4). tb_borrow_return 5). tb_boo一个曾经做过的简单…

数据库连接池_DataSource_数据源(简单介绍C3P0和Druid)

文章目录概念好处实现C3P0基本使用配置文件druid下载 jar 包配置文件演示代码定义工具类示例代码概念 数据库连接池其实就是一个容器&#xff0c;而这个容器其实就是一个集合&#xff0c;这个集合存放着多个数据库连接对象。 系统在初始化的时候&#xff0c;将创建一定数量的数…

graal java_使用SparkJava和Graal的本机微服务

graal java使用SparkJava编写的微服务只是使用标准Java库的普通Java代码。 没有注释魔术&#xff0c;只有代码。 这种简单的编程风格的优点在于&#xff0c;它很简单。 非常简单&#xff0c;以至于Graal本机编译器只需编译就不会闪烁 &#xff0c;这对于例如Spring之类的更复杂…

python消息订阅_python实现发布订阅

订阅者&#xff1a;import redisrc redis.StrictRedis(host‘127.0.0.1‘, port‘6379‘, db0)ps rc.pubsub()ps.subscribe(‘lbky‘) # 从lbky订阅消息for item in ps.listen(): # 监听状态&#xff1a;有消息发布了就拿过来print(item)if item[‘type‘] ‘message‘:prin…

使用JDBC连接数据库时,SQL语句中提示:Unable to resolve table...(原因:数据源未配置)

文章目录方法一、添加数据源方法二、输入全限定表名在 IDEA 中的 Java 代码中写 SQL 语句时&#xff0c;出现如下图所示的错误提示&#xff1a;方法一、添加数据源 要解决上面红色警告的问题&#xff0c;只需要添加数据源就可以解决。 方法二、输入全限定表名 前提&#xff1…

测试反模式冰激凌模式的不足_单元测试反模式,完整列表

测试反模式冰激凌模式的不足我前段时间写过有关OOP中的反模式的文章 。 现在该写单元测试反模式了&#xff0c;因为它们也存在&#xff0c;并且有很多。 我将尝试在列表中包括我知道的每个示例。 如果您认识其他任何人&#xff0c;请通过请求请求将其添加&#xff0c;或在下面发…

mysql导入三个基本表_mysql 基础导入导出

导入导出mysqldump导出&#xff1a;mysqldump -u root -p --databases 数据库1 数据库2 > xxx.sql导入&#xff1a;系统命令行&#xff1a; MySQL -u用户名 -p密码 常见选项&#xff1a;--all-databases, -A&#xff1a; 备份所有数据库--databases, -B&#xff1a; 用于备份…

Java代码中方法的特殊修饰符/修饰词/关键字

文章目录nativesynchronizednative 用该修饰符定义的方法在类中没有实现&#xff0c;而大多数情况下该方法的实现是用C、C编写的。 synchronized 多线程的支持。用该修饰符定义的方法被调用时&#xff0c;没有其它线程能够调用该方法&#xff0c;其它的 synchronized 方法也…

aws dynamodb_带有AWS DynamoDB的React式Spring Webflux

aws dynamodbAWS已经发布了Java版本2的AWS开发工具包 &#xff0c;该开发工具包现在支持针对不同AWS服务的API调用的非阻塞IO。 在本文中&#xff0c;我将探讨如何使用AWS开发工具包2.x的DynamoDB API以及如何使用Spring Webflux堆栈公开响应式端点-这种方式&#xff0c;应用程…

centos6.5 rpm安装mysql_CentOS6.5系统下RPM包安装MySQL5.6(转)

1.查看操作系统相关信息。[rootlinuxidc ~]# cat /etc/issueCentOS release 6.5 (Final)Kernel \r on an \m[rootlinuxidc ~]# uname -aLinux linuxidc 2.6.32-431.el6.x86_64 #1 SMP Fri Nov 22 03:15:09 UTC 2013 x86_64 x86_64 x86_64 GNU/Linux2.创建需要下载rpm软件包的目…

对象作为参数示例java_功能Java示例 第6部分–用作参数

对象作为参数示例java这是称为“ Functional Java by Example”的系列文章的第6部分。 我在本系列的每个部分中开发的示例是某种“提要处理程序”&#xff0c;用于处理文档。 在前面的部分&#xff0c;我们试图通过移动尽可能多的副作用&#xff0c;如IO&#xff0c;该系统的外…

为什么Java在后来的版本中,给接口增加了默认方法、静态方法、私有方法?

在业务发展过程中&#xff0c;发现某个功能是所有子类都需要的&#xff0c;那么我们该怎么办&#xff1f;给接口增加抽象方法吗&#xff1f;如果直接在接口增加抽象方法&#xff0c;那么所有已经写好的具体实现类就会报编译错误。因为具体类必须实现接口的全部抽象方法。这样就…

linux 源码包安装mysql_LINUX下源码包安装mysql

tar xvfz mysql-5.1.50-linux-i686-glibc23.tar.gz -C /usr/local/解压到的目录cd /usr/local/[rootdrbd2 local]# ln -sv mysql-5.1.50-linux-i686-glibc23 mysql(创建连接)groupadd mysql 添加mysql的用户组useradd -g mysql mysql 增加mysql用户并把其加入mysql组cd mysql[r…

jdk 安全属性_系统属性的JDK 12 Javadoc标记

jdk 安全属性JDK 12 Early Access Build 20 &#xff08; 2018/11/15 &#xff09;可用&#xff0c;可以用来试用新的Javadoc标签{systemProperty} 。 新的{systemProperty} Javadoc标记在core-libs-dev邮件列表消息“ FYI&#xff1a;用于记录系统属性的新javadoc标记 ”中进行…

Lambda表达式的学习

文章目录函数式编程思想函数式接口Lambda 的使用前提Lambda 的标准格式Lambda 极简特性演示代码函数式编程思想 与面向对象编程思想的区别&#xff1a; 1.面向对象的思想是做一件事情&#xff0c;找一个能解决这个事情的对象&#xff0c;调用对象的方法来完成事情 2.函数式编程…

公证服务信息_使用多个公证员提高网络吞吐量

公证服务信息您是否需要高吞吐量的Corda网络&#xff1f; 网络的吞吐量是否稳定&#xff1f; 您是否已经从其他领域挤出了所有可能的表现&#xff1f; 如果您对这些问题的回答是“是”&#xff0c;那么我可能会为您提供一些有用的信息。 我列出了这些问题&#xff0c;以减少您过…

java判断手机号_java使用正则表达式判断手机号的方法示例

本文实例讲述了java使用正则表达式判断手机号的方法。分享给大家供大家参考&#xff0c;具体如下&#xff1a;要更加准确的匹配手机号码只匹配11位数字是不够的&#xff0c;比如说就没有以144开始的号码段&#xff0c;故先要整清楚现在已经开放了多少个号码段&#xff0c;国家号…

Spring JDBC的学习

文章目录介绍使用步骤常用方法示例代码介绍 所谓 Spring JDBC&#xff0c;是 Spring 框架对 JDBC 的简单封装。提供了一个 JdbcTemplate 对象简化 JDBC 的开发。 使用步骤 步骤&#xff1a; 1.导入相关的 jar 包 2.创建 JdbcTemplate 对象&#xff0c;依赖于数据源 DataSo…

编写脚本电脑怎么编写界面_在任何无法理解的情况下,请编写脚本

编写脚本电脑怎么编写界面脚本编写是使您的应用程序在运行时就可根据客户需求进行调整的最流行的方法之一。 与往常一样&#xff0c;此方法不仅带来好处&#xff0c;例如&#xff0c;在灵活性和可管理性之间存在众所周知的折衷方案。 本文不是从理论上讨论优缺点的文章之一&…

stack java实现_Stack (堆栈)使用JAVA实现

代码如下&#xff1a;import java.util.AbstractList;import java.util.Arrays;import java.util.Iterator;import java.util.List;import java.util.RandomAccess;public class Stack extends AbstractListimplements List, RandomAccess, Cloneable, java.io.Serializable{pr…