In a Spock Specification any line in expect: or then: block is evaluated and asserted as boolean
, unless it has signature with return type void
.
I've noticed that there is something odd going on for methods declared as void
on any class inheriting from Navigator
(for example Page
or Module
classes).
Let say we have such example:
class NavigationSpec extends GebSpec {
def 'Collections page has a right header'() {
when:
to CollectionsPage
then:
hasHeaderText('Collections')
}
}
The hasHeaderText()
method is defined within CollectionsPage
class as follows:
class CollectionsPage extends Page {
static url = 'movies/collections'
void hasHeaderText(String expectedText) {
assert true
}
}
On purpose I'm just asserting true
over there so it should never fail. Even though it fails with an error:
Condition not satisfied:
hasHeaderText('Collections')
|
null
How and why a void
method call result is evaluated as null
?
I know how to 'fix it'. It's enough to declare the method return type as boolean
and return true
. This is ugly though as following all the asserts otherwise unnecessary return true
has to be added like:
boolean hasHeaderText(String expectedText) {
assert header.text() == expectedText
return true
}
This causes only noise though. Is there any way to prevent Geb from returning null
from void
methods?
I'm, of course, aware that this specific case could go like:
boolean hasHeaderText(String expectedText) {
header.text() == expectedText`
}
This doesn't explain the oddity of lost void
return type, not to mention we loose meaningful assert failure message with such approach.
expectedText
outside of the method is far from what I would like to achieve. Power assert elaborated failure messages are lost (think about comparing two maps for example) and text has to be repeated each time the method is used (DRY). I consider this to be a Geb bug – Hydra