Is there a way to prevent Geb from returning from empty methods?

In the Spock specification, any string is expected: or , and then: will be evaluated and approved as boolean , unless it has a signature with a return type of void .

I noticed that for methods declared as void , there is something strange for any class that inherits from Navigator (for example, Page or Module classes).

Say we have an example like this:

 class NavigationSpec extends GebSpec { def 'Collections page has a right header'() { when: to CollectionsPage then: hasHeaderText('Collections') } } 

The hasHeaderText() method is defined in the CollectionsPage class as follows:

 class CollectionsPage extends Page { static url = 'movies/collections' void hasHeaderText(String expectedText) { assert true } } 

For the purpose, I simply state true there, so it should never fail. Although the error fails with the error:

 Condition not satisfied: hasHeaderText('Collections') | null 

How and why is the result of calling the void method evaluated as null ?

I know how to fix it. This is enough to declare the return type of the method as boolean and return true . This is ugly, though, like all other statements, otherwise unnecessary return true should be added as:

 boolean hasHeaderText(String expectedText) { assert header.text() == expectedText return true } 

It causes only noise. Is there a way to prevent Geb from returning null methods from void ?

Of course, I know that this particular case may look like this:

 boolean hasHeaderText(String expectedText) { header.text() == expectedText` } 

This does not explain the strangeness of the lost return type of the void type, not to mention the fact that we are losing a meaningful error message with this approach.

+5
source share
2 answers

This is part of the Groovy language that each method returns a value. This allows you to use any method in expressions or as lambdas.

All methods declared void return null .

Unless you explicitly have a return statement, the result of the last expression in your method is returned.

You can look at the bytecode ... even if you declare a return type, you actually don't need to return anything, since Groovy returns null by default:

 // returns null String callMe() { } static void main(args) { def x = callMe() assert x == null println "OK!" } 

Since Spock will claim anything in the then block, which is not a simple assignment, you need to avoid doing anything other than logical statements in the then block. Even when assigning a variable, even if it is allowed, you should avoid ... It is difficult to keep the tests clean and clear, and adhering to these recommendations will really work for you in the long run, and not against you.

So, the correct way to write the statement you want is to make your method return a boolean:

 boolean hasHeaderText(String expectedText) { header.text() == expectedText } 

And use it in the then block:

 then: 'The header has the expected text #expectedText' hasHeaderText expectedText 

It looks good if you ask me.

EDIT

I noticed that Groovy / Spock will not actually approve the result of the usual void method even in the then block ... What probably happens here, I have the usual void method, you seem to be calling the dynamic CollectionsPage method (I think the game Hebe is in the game), which means that maybe Transformer Spock AST is not able to verify the signature of the method that you are calling, so it correctly assumes that it should approve the result ... at least what it looks like.

+4
source

@Renato is correct in the edited part of his answer - your call to the void method is approved by Spock because it is a dynamic call and Spock cannot understand that you are calling the void method and eagerly approves the call. If you changed your code to:

 class NavigationSpec extends GebSpec { def 'Collections page has a right header'() { when: CollectionsPage collectionsPage = to CollectionsPage then: collectionsPage.hasHeaderText('Collections') } } 

then it will not be confirmed.

+3
source

Source: https://habr.com/ru/post/1246873/


All Articles