当前位置: 首页 > news >正文

精品课网站建设电商网站推广渠道

精品课网站建设,电商网站推广渠道,物联网网站的建设和维护,宁夏固原建设网站junit单元测试断言简而言之#xff0c;本章涵盖了各种单元测试声明技术。 它详细说明了内置机制#xff0c; Hamcrest匹配器和AssertJ断言的优缺点 。 正在进行的示例扩大了主题#xff0c;并说明了如何创建和使用自定义匹配器/断言。 单元测试断言 信任但要验证 罗纳德里… junit单元测试断言 简而言之本章涵盖了各种单元测试声明技术。 它详细说明了内置机制 Hamcrest匹配器和AssertJ断言的优缺点 。 正在进行的示例扩大了主题并说明了如何创建和使用自定义匹配器/断言。 单元测试断言 信任但要验证 罗纳德·里根Ronald Reagan 后期测试结构解释了为什么单元测试通常分阶段进行。 它澄清说 真正的测试即结果验证在第三阶段进行。 但是到目前为止我们只看到了一些简单的示例主要使用了JUnit的内置机制。 如Hello World所示验证基于错误类型AssertionError 。 这是编写所谓的自检测试的基础。 单元测试断言将谓词评估为true或false 。 如果为false 则抛出AssertionError 。 JUnit运行时捕获此错误并将测试报告为失败。 以下各节将介绍三种较流行的单元测试断言变体。 断言 JUnit的内置断言机制由类org.junit.Assert 。 它提供了两种静态方法来简化测试验证。 以下代码片段概述了可用方法模式的用法 fail(); fail( Houston, Weve Got a Problem. );assertNull( actual ); assertNull( Identifier must not be null.,actual );assertTrue( counter.hasNext() ); assertTrue( Counter should have a successor.,counter.hasNext() );assertEquals( LOWER_BOUND, actual ); assertEquals( Number should be lower bound value., LOWER_BOUND,actual ); Assert#fail()无条件地引发断言错误。 这对于标记不完整的测试或确保引发了预期的异常很有帮助另请参见“ 测试结构”中的“预期异常”部分。 Assert#assertXXX(Object)用于验证变量的初始化状态。 为此存在两个称为assertNull(Object)和assertNotNull(Object) 。 Assert#assertXXX(boolean)方法测试boolean参数传递的预期条件。 调用assertTrue(boolean)期望条件为true 而assertFalse(boolean)期望相反。 Assert#assertXXX(Object,Object)和Assert#assertXXX(value,value)方法用于对值对象和数组进行比较验证。 尽管结果没有区别但通常的做法是将期望值作为第一个参数将实际值作为第二个参数。 所有这些类型的方法都提供带有String参数的重载版本。 如果发生故障此参数将合并到断言错误消息中。 许多人认为这有助于更清楚地指定失败原因。 其他人则认为此类消息混乱使测试更难阅读。 乍一看这种单元测试断言似乎很直观。 这就是为什么我在前面的章节中使用它进行入门的原因。 此外它仍然非常流行并且工具很好地支持故障报告。 但是在需要更复杂的谓词的断言的表达性方面也受到一定限制。 Hamcrest Hamcrest是一个旨在提供用于创建灵活的意图表达的API的库。 该实用程序提供了称为Matcher的可嵌套谓词。 这些允许以某种方式编写复杂的验证条件许多开发人员认为比布尔运算符更易于阅读。 MatcherAssert类支持单元测试断言。 为此它提供了静态的assertThat(T, Matcher 方法。 传递的第一个参数是要验证的值或对象。 第二个谓词用于评估第一个谓词。 assertThat( actual, equalTo( IN_RANGE_NUMBER ) ); 如您所见匹配器方法模仿自然语言的流程以提高可读性。 以下代码片段更加清楚了此意图。 这使用is(Matcher 方法来修饰实际的表达式。 assertThat( actual, is( equalTo( IN_RANGE_NUMBER ) ) ); MatcherAssert.assertThat(...)存在另外两个签名。 首先有一个采用布尔参数而不是Matcher参数的变量。 它的行为与Assert.assertTrue(boolean) 。 第二个变体将一个附加的String传递给该方法。 这可以用来提高故障消息的表达能力 assertThat( Actual number must not be equals to lower bound value., actual, is( not( equalTo( LOWER_BOUND ) ) ) ); 在失败的情况下给定验证的错误消息如下所示 Hamcrest带有一组有用的匹配器。 图书馆在线文档的“常见匹配项”部分中列出了最重要的部分。 但是对于特定于域的问题如果有合适的匹配器通常可以提高单元测试断言的可读性。 因此该库允许编写自定义匹配器。 让我们返回教程的示例来讨论该主题。 首先我们对该场景进行调整以使其更合理。 假设NumberRangeCounter.next()返回的是RangeNumber类型而不是简单的int值 public class RangeNumber {private final String rangeIdentifier;private final int value;RangeNumber( String rangeIdentifier, int value ) {this.rangeIdentifier rangeIdentifier;this.value value;}public String getRangeIdentifier() {return rangeIdentifier;}public int getValue() {return value;} } 我们可以使用自定义匹配器来检查NumberRangeCounter#next()的返回值是否在计数器的定义数字范围内 RangeNumber actual counter.next();assertThat( actual, is( inRangeOf( LOWER_BOUND, RANGE ) ) ); 适当的自定义匹配器可以扩展抽象类TypeSafeMatcherT 。 该基类处理null检查和类型安全。 可能的实现如下所示。 请注意如何添加工厂方法inRangeOf(int,int)以便于使用 public class InRangeMatcher extends TypeSafeMatcherRangeNumber {private final int lowerBound;private final int upperBound;InRangeMatcher( int lowerBound, int range ) {this.lowerBound lowerBound;this.upperBound lowerBound range;}Overridepublic void describeTo( Description description ) {String text format( between %s and %s., lowerBound, upperBound );description.appendText( text );}Overrideprotected void describeMismatchSafely(RangeNumber item, Description description ){description.appendText( was ).appendValue( item.getValue() );}Overrideprotected boolean matchesSafely( RangeNumber toMatch ) {return lowerBound toMatch.getValue() upperBound toMatch.getValue();}public static MatcherRangeNumber inRangeOf( int lowerBound, int range ) {return new InRangeMatcher( lowerBound, range );} } 对于给定的示例工作量可能会有些夸大。 但它显示了如何使用自定义匹配器消除先前帖子中有点神奇的IN_RANGE_NUMBER常量。 除了新类型外还强制声明语句的编译时类型安全。 这意味着例如String参数将不被接受进行验证。 下图显示了使用我们的自定义匹配器时测试结果失败的样子 很容易看出describeTo和describeMismatchSafely的实现以哪种方式影响故障消息。 它表示期望值应该在指定的下限和计算的上限1之间 并跟在实际值之后。 有点不幸的是JUnit扩展了其Assert类的API以提供一组assertThat…方法。 这些方法实际上复制了MatcherAssert提供的API。 实际上这些方法的实现委托给这种类型的相应方法。 尽管这可能只是个小问题但我认为值得一提。 由于这种方法JUnit与Hamcrest库牢固地联系在一起。 这种依赖性有时会导致问题。 特别是与其他库一起使用时通过合并自己的hamcrest版本的副本情况甚至更糟…… Hamcrest的单元测试主张并非没有竞争。 虽然关于每次测试一个确定与每个测试 一个概念的讨论超出了本文的讨论范围但后一种观点的支持者可能认为该库的验证声明过于嘈杂。 尤其是当一个概念需要多个断言时。 这就是为什么我必须在本章中添加另一部分 断言 在“ 测试跑步者”中示例片段之一使用了两个assertXXX语句。 这些验证期望的异常是IllegalArgumentException的实例并提供特定的错误消息。 该段看起来像这样 Throwable actual ...assertTrue( actual instanceof IllegalArgumentException ); assertEquals( EXPECTED_ERROR_MESSAGE, actual.getMessage() ); 上一节教我们如何使用Hamcrest改进代码。 但是如果您碰巧是该库的新手您可能会想知道要使用哪个表达式。 或打字可能会感到不舒服。 无论如何多个assertThat语句会加在一起。 AssertJ库通过为Java提供流畅的断言来努力改善这一点。 流畅的接口 API的目的是提供一种易于阅读的富有表现力的编程风格从而减少胶合代码并简化键入。 那么如何使用这种方法来重构上面的代码 import static org.assertj.core.api.Assertions.assertThat; 与其他方法类似AssertJ提供了一个实用程序类该类提供了一组静态assertThat方法。 但是这些方法针对给定的参数类型返回特定的断言实现。 这就是所谓的语句链接的起点。 Throwable actual ...assertThat( actual ).isInstanceOf( IllegalArgumentException.class ).hasMessage( EXPECTED_ERROR_MESSAGE ); 旁观者认为可读性在某种程度上得到了扩展但无论如何都可以用更紧凑的样式来写断言。 了解如何流畅地添加与被测特定概念相关的各种验证方面。 这种编程方法支持有效的类型输入因为IDE的内容辅助可以提供给定值类型的可用谓词列表。 因此您想向后世提供表现力的失败消息吗 一种可能是使用describedAs作为链中的第一个链接来注释整个块 Throwable actual ...assertThat( actual ).describedAs( Expected exception does not match specification. ).hasMessage( EXPECTED_ERROR_MESSAGE ).isInstanceOf( NullPointerException.class ); 该代码段期望使用NPE但假设在运行时抛出了IAE。 然后失败的测试运行将提供如下消息 也许您希望根据给定的失败原因使您的消息更加细微。 在这种情况下您可以在每个验证规范之前添加一条describedAs语句 Throwable actual ...assertThat( actual ).describedAs( Message does not match specification. ).hasMessage( EXPECTED_ERROR_MESSAGE ).describedAs( Exception type does not match specification. ).isInstanceOf( NullPointerException.class ); 还有更多的AssertJ功能可供探索。 但是要使该帖子保持在范围内请参阅实用程序的在线文档以获取更多信息。 但是在结束之前让我们再次看一下范围内验证示例。 这可以通过自定义断言来解决 public class RangeCounterAssertionextends AbstractAssertRangeCounterAssertion, RangeCounter {private static final String ERR_IN_RANGE_OF Expected value to be between %s and %s, but was %s;private static final String ERR_RANGE_ID Expected range identifier to be %s, but was %s;public static RangeCounterAssertion assertThat( RangeCounter actual ) {return new RangeCounterAssertion( actual );}public InRangeAssertion hasRangeIdentifier( String expected ) {isNotNull();if( !actual.getRangeIdentifier().equals( expected ) ) {failWithMessage( ERR_RANGE_ID, expected, actual.getRangeIdentifier() );}return this;}public RangeCounterAssertion isInRangeOf( int lowerBound, int range ) {isNotNull();int upperBound lowerBound range;if( !isInInterval( lowerBound, upperBound ) ) {int actualValue actual.getValue();failWithMessage( ERR_IN_RANGE_OF, lowerBound, upperBound, actualValue );}return this;}private boolean isInInterval( int lowerBound, int upperBound ) {return actual.getValue() lowerBound actual.getValue() upperBound;}private RangeCounterAssertion( Integer actual ) {super( actual, RangeCounterAssertion.class );} } 自定义断言是扩展AbstractAssert常见做法。 第一个通用参数是断言的类型本身。 流利的链接样式需要它。 第二种是断言所基于的类型。 该实现提供了两种附加的验证方法可以按照以下示例进行链接。 因此这些方法将返回断言实例本身。 请注意 isNotNull()的调用如何确保我们要声明的实际RangeNumber不为null 。 定制断言由其工厂方法assertThat(RangeNumber) 。 由于它继承了可用的基本检查因此断言可以开箱即用地验证非常复杂的规范。 RangeNumber first ... RangeNumber second ...assertThat( first ).isInRangeOf( LOWER_BOUND, RANGE ).hasRangeIdentifier( EXPECTED_RANGE_ID ).isNotSameAs( second ); 为了完整RangNumberAssertion 以下是RangNumberAssertion的实际运行方式 不幸的是不可能在同一测试用例中使用两种不同的断言类型和静态导入。 当然假定这些类型遵循assertThat(...)命名约定。 为了避免这种情况文档建议扩展实用程序类Assertions 。 这样的扩展可用于提供静态的assertThat方法作为所有项目自定义断言的入口。 通过在整个项目中使用此自定义实用程序类不会发生导入冲突。 在为所有断言提供单一入口点的部分中可以找到详细的描述在线文档中有关定制断言的 yours AssertJ 。 流利的API的另一个问题是单行链接的语句可能更难调试。 这是因为调试器可能无法在链中设置断点。 此外可能不清楚哪个方法调用已引起异常。 但是正如Wikipedia所说的那样可以通过将语句分成多行来克服这些问题如上面的示例所示。 这样用户可以在链中设置断点轻松地逐行浏览代码。 结论 简而言之JUnit的这一章介绍了不同的单元测试断言方法例如该工具的内置机制Hamcrest匹配器和AssertJ断言。 它概述了一些优缺点并通过本教程的持续示例对主题进行了扩展。 此外还展示了如何创建和使用自定义匹配器和断言。 尽管基于Assert的机制肯定是过时的且不太面向对象但它仍然具有它的提倡者。 Hamcrest匹配器提供断言和谓词定义的清晰分隔而AssertJ断言以紧凑且易于使用的编程样式进行评分。 所以现在您选择太多了…… 请注意这将是本教程有关JUnit测试要点的最后一章。 这并不意味着没有更多要说的了。 恰恰相反 但这将超出此迷你系列量身定制的范围。 而且您知道他们在说什么 总是让他们想要更多… 嗯我想知道区间边界是否会比下限和范围更直观... 翻译自: https://www.javacodegeeks.com/2014/09/junit-in-a-nutshell-unit-test-assertion.htmljunit单元测试断言
http://www.huolong8.cn/news/319646/

相关文章:

  • 开发网站监控平台电影网站备案
  • 小说网站防盗做的好处免费域名注册推荐
  • 信息发布网无锡网站seo外包
  • app设计大赛新网站如何做seo优化
  • 泰安商城网站开发设计小型网站开发需要什么步骤
  • 南昌seo网站推广费用网站的内部链接如何做
  • 网站设计与制作平台南宁网站seo大概多少钱
  • 现在最好的企业网站管理系统线上销售平台都有哪些
  • 网站平台建设实训总结济南城乡建设局
  • 网站建设后备案多少钱小说排行榜
  • 高端html5网站建设织梦模板 dedecms5.7织梦网络公司源织梦企业模板去一品资源网
  • 上海网站设计图片网站外链隐形框架是什么
  • 2020国内十大小说网站排名网站建设陆金手指谷哥9
  • 网站打开乱码企业网站建设公司怎么收费
  • 档案信息网站建设的意义可以投放广告的网站
  • 潍坊网站关键词aspx网站开发
  • 上海网站络公司移动开发网站建设
  • 男女做暖暖的视频试看网站网页界面设计中主要包括哪三个方面
  • 南京网站建设外包个人网站设计风格
  • 网站企业网站建设需求文档网站建设最简单的教程视频
  • 个人网站怎么推广怎么增加网站外链
  • 网站建设的风险分析小红书推广价目表
  • 宁波哪里做网站的广州奕联网站开发
  • 免费搭建永久网站步骤山东省建设工程招标投标信息网
  • 企业定制网站价格表如何进行电子商务网站建设规划
  • 网站编辑信息怎么做凡科网页登录
  • 衡阳建设网站公司网站后台 语言
  • 湖州网站集约化平台智能建站平台z
  • 昆明做网站的公司哪家好企业网站的建设目的有什么
  • 公司网站建设招标文件范本国内html5网站案例