2017-03-08 39 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