在Spock规范中,期望的任何行:或者然后: block被评估并断言为boolean,除非它具有返回类型的签名void.
我注意到void在继承的任何类Navigator(例如Page或Module类)上声明的方法有些奇怪.
假设我们有这样的例子:
class NavigationSpec extends GebSpec {
def 'Collections page has a right header'() {
when:
to CollectionsPage
then:
hasHeaderText('Collections')
}
}
Run Code Online (Sandbox Code Playgroud)
该hasHeaderText()方法在CollectionsPage类中定义如下:
class CollectionsPage extends Page {
static url = 'movies/collections'
void hasHeaderText(String expectedText) {
assert true
}
}
Run Code Online (Sandbox Code Playgroud)
故意我只是true在那里断言所以它永远不会失败.即使它失败并出现错误:
Condition not satisfied:
hasHeaderText('Collections')
|
null
Run Code Online (Sandbox Code Playgroud)
void方法调用结果的评估方式和原因是null什么?
我知道如何"修复它".将方法返回类型声明为return boolean并返回就足够了true.这是丑陋的,但是跟随所有断言,否则return true必须添加如下:
boolean hasHeaderText(String expectedText) {
assert header.text() == expectedText
return true
}
Run Code Online (Sandbox Code Playgroud)
这只会产生噪音.有没有办法防止Geb null从void方法返回?
当然,我知道这个具体案例可能是这样的:
boolean hasHeaderText(String expectedText) {
header.text() == expectedText`
}
Run Code Online (Sandbox Code Playgroud)
这并不能解释丢失void返回类型的奇怪之处,更不用说我们用这种方法松散有意义的断言失败消息.
每个方法都会返回一个值,这是 Groovy 语言的一部分。这允许在表达式中使用任何方法或作为 lambda。
所有声明为voidreturn 的方法null。
如果您没有显式地使用任何 return 语句,则将返回方法中最后一个表达式的结果。
您可以查看字节码...即使您声明了返回类型,您实际上也不需要返回任何内容,因为默认情况下,Groovy 将返回 null:
// returns null
String callMe() { }
static void main(args) {
def x = callMe()
assert x == null
println "OK!"
}
Run Code Online (Sandbox Code Playgroud)
因为 Spock 会断言块中的任何then内容,这不是简单的赋值,所以您需要避免在块中执行除布尔断言之外的任何操作then。即使分配一个变量,虽然允许,但应该避免......保持测试干净和清晰是很困难的,并且遵守这些准则从长远来看确实对你有用,而不是对你不利。
因此,编写所需断言的正确方法是使方法返回布尔值:
boolean hasHeaderText(String expectedText) {
header.text() == expectedText
}
Run Code Online (Sandbox Code Playgroud)
并在then块中使用它:
then: 'The header has the expected text #expectedText'
hasHeaderText expectedText
Run Code Online (Sandbox Code Playgroud)
如果你问我的话,看起来不错。
编辑
我注意到 Groovy/Spock 实际上不会断言正常void 方法的结果,即使在then块中...这里可能发生的情况是您没有正常的void 方法,您似乎正在调用动态方法CollectionsPage(我猜这就是 Geb 的魔力),这意味着 Spock AST Transformer 可能没有机会检查您正在调用的方法的签名,因此它正确地假设它必须断言结果。 . 至少看起来是这样。
| 归档时间: |
|
| 查看次数: |
855 次 |
| 最近记录: |