2017-03-08 87 views
2

将闭包或方法中的语句内联到断言中,以便断言失败时可以打印该语句吗?如何在Groovy中声明来自声明的方法或闭包语句

如果我们简单的声明一样assert 10 == (20 - 11)然后Groovy的功率断言打印好听一点像:

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

但是,如果我们提取的语句转换成像一个封闭:

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

则输出将是更少的信息:

assert c(10) 
     | 
     false 

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

回答

1

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

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

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

输出:

java.lang.AssertionError: Comparison failed. Expression: c.call(10, (20 - 11)) at 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: Comparison failed: 10 vs 9. Expression: (arg1 == arg2). Values: arg1 = 10, arg2 = 9
at Script1$_run_closure1.doCall(Script1.groovy:1)
at Script1.run(Script1.groovy:2)

你写这样更封闭,具体的操作,如assertGreaterThanassertLessThan

方法#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 is not equal to 9. Expression: (arg1 == arg2). Values: arg1 = 10, arg2 = 9
at Script1$_run_closure1.doCall(Script1.groovy:1)
at 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 is not less than 9. Expression: (op1 < op2). Values: op1 = 10, op2 = 9
at Script1$_run_closure2.doCall(Script1.groovy:2)
at Script1$_run_closure1.doCall(Script1.groovy:1)
at Script1.run(Script1.groovy:2)

如果你想要去的简单的方法,直接使用equal断言,然后方法2是正确的。当然,你是最好的选择哪一个更适合你的需求。

+0

感谢您的全面回答。我目前正在使用第二种方法,因为断言必须很好地封装。考虑布尔断言而不是assert语句的原因是为了很好地支持像anyMatch这样的集合的断言。但是,如果它不容易实现并且以不太美丽的方式实现,那么我可以没有它。 –

+0

如果有帮助,感谢您是否可以接受上述答案。 – Rao