在断言异常时,如何知道何时在ScalaTest Matchers中使用`a`,`an`或`the`?

时间:2019-11-28 01:45:32

标签: scala scalatest

我正在阅读ScalaTest文档中关于Testing Exceptions的部分,并查看

之类的示例
an [IndexOutOfBoundsException] should be thrownBy s.charAt(-1)

我测试了a,它也可以工作

a [IndexOutOfBoundsException] should be thrownBy s.charAt(-1)

val thrown = the [IndexOutOfBoundsException] thrownBy s.charAt(-1)

我很困惑,关于这些关键字的文档很少甚至没有。 谢谢

2 个答案:

答案 0 :(得分:3)

不幸的是,scalatest docs并没有那么详细,但是或多或少是这样的:

当您只想断言所引发的异常类型时,应该使用a,但不声明其内容(例如,消息,嵌套异常等),但是实现和行为是相同的

当异常类以元音开头时(仅出于英语拼写规则),应使用an。在幕后,它们由不同的机器(AMatcherAnMatcher)表示,但是行为实际上是相同的(我所观察到的唯一区别是在其中使用了“ a”和“ an”)失败消息)

要断言所引发的异常类型时应使用the,并且还应捕获异常实例以执行其他断言(针对消息,嵌套异常等)。

答案 1 :(得分:2)

从库源代码aan中可以看到,它们是完全相同的:

  /**
   * This method enables the following syntax: 
   *
   * <pre class="stHighlight">
   * a [RuntimeException] should be thrownBy { ... }
   * ^
   * </pre>
   */
  def a[T: ClassTag]: ResultOfATypeInvocation[T] =
    new ResultOfATypeInvocation(classTag)

  /**
   * This method enables the following syntax: 
   *
   * <pre class="stHighlight">
   * an [Exception] should be thrownBy { ... }
   * ^
   * </pre>
   */
  def an[T : ClassTag]: ResultOfAnTypeInvocation[T] =
    new ResultOfAnTypeInvocation(classTag)

  /**
   * This method enables the following syntax: 
   *
   * <pre class="stHighlight">
   * the [FileNotFoundException] should be thrownBy { ... }
   * ^
   * </pre>
   */
  def the[T : ClassTag](implicit pos: source.Position): ResultOfTheTypeInvocation[T] =
    new ResultOfTheTypeInvocation(classTag, pos)

但是,如果需要使用the之类的方法,getMessage可让您进一步检查异常。您引用的文档中的示例:

the [ArithmeticException] thrownBy 1 / 0 should have message "/ by zero"

如果您只关心正确的异常类型,请使用a / an。如果您需要检查异常类型及其消息,请使用the

由于这些匹配器的字符串表示形式(如果您关心代码中的语法),因此生成的每个测试失败的文本都会略有不同:

// from ResultOfATypeInvocation:
override def toString: String = "a [" + clazz.getName + "]"

vs

// from ResultOfAnTypeInvocation:
override def toString: String = "an [" + clazz.getName + "]" 

例如。