0

Reading http://spockframework.github.io/spock/docs/1.0/data_driven_testing.html, it seems that data tables are a convenient, readable way to structure test inputs. I'd like to structure my test output in a similar way.

I have a method under test which returns an Iterable<Entry<String, String>>. I have the following Spock test case, but something tells me there is a way I can make Spock do more of this for me. This is essentially just Java code, so I suspect there is a groovier way. Can this be simplified?

def "iterate" () {
    given:
    Iterator expected =
    ['one'    : 'a',
     'two'    : 'b',
     'three'  : 'c',
     'four'   : 'd',
     'five'   : 'e',
     'six'    : 'f'].entrySet().iterator()

    when:
    Iterable<Entry<String, String>> actual = testClass.method()

    then:
    for (def entry : actual) {
        assert entry == expected.next()
    }
}
jaco0646
  • 15,303
  • 7
  • 59
  • 83

1 Answers1

0

The result of this test is unpredictable since iteration order over set is not defined (see here) and when comparing elements of two sets in the way in the code it will almost fail for sure.

Here's how it should look:

def "iterate" () {
    given:
    Iterator expected =
    ['one'    : 'a',
     'two'    : 'b',
     'three'  : 'c',
     'four'   : 'd',
     'five'   : 'e',
     'six'    : 'f'].entrySet()

    when:
    Iterable<Entry<String, String>> actual = testClass.method()

    then:
    expected == actual as Set
}
Community
  • 1
  • 1
Opal
  • 81,889
  • 28
  • 189
  • 210
  • Groovy by default uses LinkedHashMap (and LinkedHashSet) so the keys are ordered. My original code works; I only suspected there was a way that I could avoid explicitly calling the iterator. Coercing the Iterable is a good idea, but unfortunately the equality comparison fails: the contents are equal but the underlying types are still different. – jaco0646 Feb 03 '15 at 16:22