3

I am working with:

  • Spock Core
  • Spock Reports
  • Spock Spring
  • Spring MVC Testing

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?

Manuel Jordan
  • 15,253
  • 21
  • 95
  • 158

1 Answers1

2

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?

rdmueller
  • 10,742
  • 10
  • 69
  • 126
  • I've tested your solution, it does not work. Firstly I receive an error about I can't declare `when` after the latest `then`. And the variable always is null. – Manuel Jordan Nov 25 '15 at 16:45
  • I just fixed the typo - the last block should be a `where`. - sorry. I will also see if I can find the time to test my answer myself in order to see if there are other problems... stay tuned... – rdmueller Nov 25 '15 at 17:28
  • thanks!. There are two problems (1) `where` can't be used after of `then`. (2) your `url <<` always fails due *NullPointer…* and something related. – Manuel Jordan Nov 26 '15 at 01:34
  • Please take a look at the added details. Regarding the `NullPointer` - I guess it results from your `FINDALL` helper method. Please make sure that it does not return `null` - it should return a list or, if it return a single item, put it in `[]` brakets as I did im my example. – rdmueller Nov 26 '15 at 20:17
  • Hello @rdmueller your code works now. Proceed to paste your code here to apply your answer how correct. yes, the trick was `[]` – Manuel Jordan Nov 29 '15 at 14:01
  • Yes. `FINDALL` returns a single string value, not a collection/list. – Manuel Jordan Nov 29 '15 at 14:06
  • Suggestion: include the explanation about `[]` in your post. I think is valuable for the audience. Thanks a lot by all! – Manuel Jordan Nov 29 '15 at 14:08