你得到這樣的輸出,因爲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