如何在Groovy中从断言方法或闭包中打印语句

时间:2017-03-08 16:38:20

标签: groovy assertion

是否有可能将闭包或方法的内联语句内联到断言中,以便在断言失败时打印它?

如果我们有像assert 10 == (20 - 11)之类的简单语句,那么Groovy的权限断言就像打印它一样:

assert 10 == (20 - 11)
          |      |
          false  9

但是,如果我们将语句提取到如下的闭包中:

def c = { arg -> arg == (20 - 11) }
assert c(10)

然后输出信息量会少得多:

assert c(10)
       |
       false

我正在开发自定义的特定测试框架,用例是将自定义断言表示为布尔闭包或方法,并从一个地方运行断言。

1 个答案:

答案 0 :(得分:1)

你得到这样的输出,closure返回布尔值,assert确实找true

方法#1 :如果你想改变输出,那么你可以将两个参数传递给closure而不是一个参数,如下所示。当然,您可能不希望在框架中将等式与静态数进行比较,因此第二个参数是有意义的。

def c = { arg1, arg2 -> arg1 == arg2 }  
assert c(10, 20-11), 'comparison failed'

<强>输出:

  

java.lang.AssertionError:比较失败。表达式:c.call(10,(20 - 11))       在Script1.run(Script1.groovy:2)

方法#2 :这里适当地更改了闭包名称,并在其内部进行断言。由于其名称为assertEqual,因此可能不会滥用其他断言,例如><

def assertEqual = { arg1, arg2 -> assert arg1 == arg2, "Comparison failed: ${arg1} vs ${arg2}" }  
assertEqual(10, 20-11)

输出:

  

java.lang.AssertionError:比较失败:10 vs 9.表达式:(arg1 == arg2)。值:arg1 = 10,arg2 = 9
      在Script1 $ _run_closure1.doCall(Script1.groovy:1)
      在Script1.run(Script1.groovy:2)

您以这种方式编写了更多闭包,例如assertGreaterThan assertLessThan用于特定操作。

方法#3 :在这里,您甚至可以将错误消息传递给闭包。

def assertEqual = { arg1, arg2, message -> assert arg1 == arg2, message(arg1, arg2) }
assertEqual(10, 20-11) {op1, op2 -> "$op1 is not equal to $op2"}

<强>输出:

  

java.lang.AssertionError:10不等于9.表达式:(arg1 == arg2)。值:arg1 = 10,arg2 = 9
      在Script1 $ _run_closure1.doCall(Script1.groovy:1)
      在Script1.run(Script1.groovy:2)

方法#4 用户可以传递operation和消息的另一种变体。您不仅可以执行equal,还可以执行其他操作。因此,将closure名称更改为myAssert

def myAssert = { arg1, arg2, expression -> expression(arg1, arg2) }
//Greater than
myAssert(10, 20-11) {op1, op2 -> assert op1 > op2, "$op1 is not greater than $op2" }
//Less than
myAssert(10, 20-11) {op1, op2 -> assert op1 < op2, "$op1 is not less than $op2" }
//Equal
myAssert(10, 20-11) {op1, op2 -> assert op1 == op2, "$op1 is not equal to $op2" }

<强>输出:

  

java.lang.AssertionError:10不小于9.表达式:(op1&lt; op2)。值:op1 = 10,op2 = 9
      在Script1 $ _run_closure2.doCall(Script1.groovy:2)
      在Script1 $ _run_closure1.doCall(Script1.groovy:1)
      在Script1.run(Script1.groovy:2)

如果您想采用简单的方法并且只使用equal断言,则方法#2 是正确的。当然,你最好选择哪一种更适合你的需要。