你得到这样的输出,因为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)
你写这样更封闭,具体的操作,如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 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是正确的。当然,你是最好的选择哪一个更适合你的需求。
感谢您的全面回答。我目前正在使用第二种方法,因为断言必须很好地封装。考虑布尔断言而不是assert语句的原因是为了很好地支持像anyMatch这样的集合的断言。但是,如果它不容易实现并且以不太美丽的方式实现,那么我可以没有它。 –
如果有帮助,感谢您是否可以接受上述答案。 – Rao