Search code examples
groovyguavaspockassertion

How to assert in Spock that list contains only some particular element?


In pure Spock/Groovy I need two separate assertions to verify that list contains some element and nothing else:

def "list has single element"() {
    given:
    def list = ['x']

    expect:
    list.size() == 1
    list.first() == 'x'
}

I can make this assertion single-line by using Guava dependency:

    expect:
    Iterables.getOnlyElement(list) == 'x'

Is there a way to do the same in single line in pure Groovy/Spock? I don't want to use Guava too much in my tests.

EDIT

Actually for such a simple example just list == ['x'] is enough. I'm looking for a non Guava solution for something more complex, when multiple assertions must be performed on this single element:

  def "list has single element"() {
        given:
        def list = [5.0]

        expect:
        def bigDecimal = Iterables.getOnlyElement(list)
        bigDecimal.scale() == 1
        bigDecimal.precision() == 2
    }

Solution

  • If creating a helper method is acceptable, one can use with():

    def "list has single element"() {
        given:
        def list = [5.0]
    
        expect:
        with onlyElementOf(list), {
            it.scale() == 1
            it.precision() == 2
        }
    }
    

    where onlyElementOf() is

     static <T> T onlyElementOf(Iterable<T> iterable) {
        Iterator iterator = iterable.iterator()
        def first = iterator.next()
        assert !iterator.hasNext(), "Iterable has more than 1 element"
        return first
    }
    

    This makes the test pretty readable.