testingspockspock-reports

Spock & Spock Reports: How print a variable valuable in Label/Block


I am working with:

and I have the following code:

def "findAll() Expected"(){

    given: "The URL being used is: /personas/xml/personas"

        url = PersonaUrlHelper.FINDALL;

    when: "When the URL is being calling with a GET"

        resultActions = mockMvc.perform(get(url)).andDo(print())

    then: "something..."

        resultActions.andExpect(status().isOk())
                     .andExpect(content().contentType(RequestMappingProducesJsonUtf8.PRODUCES_JSON_UTF_8))

}

Two observations:

One: observe given: "The URL being used is: /personas/xml/personas" where the URL/URI value has been added manually.

Two: the url variable has been defined how an instance variable, because it is common in many test methods. Therefore def String url

My question is:

how I can display the url variable in a Spock's label/block? how (given, then…)? It to be printed through Spock Reports and improve my testing documentation

I have read the following: Spocklight: Extra Data Variables for Unroll Description

It working around @Unroll. But I did realize all work around the where label/block.

I already have tried something like:

given: "The URL being used is: $url"
given: "The URL being used is: ${url}"

And does not work

I want to work around with a syntax similar like the following:

def "findAll() Expected"(){

    url = PersonaUrlHelper.FINDALL;

    given: "The URL being used is: $url"

        …. something

    when: "When the URL is being calling with a GET"

So what could be the correct configuration?

Asume I do a refactor for PersonaUrlHelper.FINDALL used in some Spring's @RequestMapping and in this test method. I don't want update manually the text in the given label/block

So what is the correct syntax?


Solution

  • Quick answer:

    I guess the where-block approach will be the right one. Use something like

    where: "When the URL is being calling with a GET"
      url << PersonaUrlHelper.FINDALL
    

    And remove the definition of url from the test. You will be able to use the url variable, since it is definied in the where-block. And you will be able to reference it from the test description as #url:

    @Unroll
    def "findAll() Expected"(){
        given: "The URL being used is: #url"
            //removed url definition
        when: "When the URL is being calling with a GET"
            resultActions = mockMvc.perform(get(url)).andDo(print())
        then: "something..."
            resultActions.andExpect(status().isOk())
                     .andExpect(content().contentType(RequestMappingProducesJsonUtf8.PRODUCES_JSON_UTF_8))
        where: "When the URL is being calling with a GET"
            url << [PersonaUrlHelper.FINDALL]
    }
    

    Another more hacky way would be to print the url just through a println url - this output is also captured afaik, but it wouldn't be as nice.

    Update: please take a look at the following spock console script: https://meetspock.appspot.com/script/5146767490285568 :

    import spock.lang.*
    
    class PersonalUrlHelper {
      final static String FINDALL = 'http://example.com'
    }
    
    class MyFirstSpec extends Specification {
      @Unroll
      def "findAll() Expected #url "(){
        given:"The URL being used is: #url"        
        when: "When URL (#url) is assigned to a"        
          def a = url    
        then: "a equals the URL (#url)"        
          a == url
        where: "the URL is fetched from another class or map in this case"        
          url << [PersonalUrlHelper.FINDALL]
      }
    }
    

    I tried to mock your script - without having your code.

    As you can see, the content of the URL is printed out in the test name. AFAIK, it will also be reflected in the texts of the different test blocks when printed out through spock-reports.

    BTW: the [] are important since they turn the returned string into a list with one element. Otherwise the string will be interpreted as lsit and the test will iterate through each character.

    Does this help?