MiamiBeach
MiamiBeach

Reputation: 3497

Spock: how can I get a context of the failed test?

def "validate my files list"() {
    when:
    new File(folder).eachFileRecurse {
        validateFile(it)
    }
    then:
    notThrown(ValidationFailedException)
    where:
    folder << ['folder1', 'folder2']
}

I have coded that simple test with Spock and Groovy. When it fails it prints:

Exception itself (...)

Expected no exception of type 'ValidationFailedException' to be thrown, but got it nevertheless

I wonder how can I print the fileName and folder1/folder2 parameter to know where the wrong data resides? The only way I see is to create Exception with message containing fileName and folderName and rethrow it from when block, but this is not very convenient.

Upvotes: 1

Views: 478

Answers (3)

dmahapatro
dmahapatro

Reputation: 50265

A workaround is required if you need fileName but I do not think test like below adds value. I would rather make sure validateFile() undertakes the logic of recursively validating each file. Therefore, @Peter's approach should be sufficient. Anyways, here is how the fileName can be printed inefficiently, just for the sake of testing:

import spock.lang.*

@Unroll
class SampleSpec extends Specification {
    @Shared filesUnderFolder1, filesUnderFolder2

    void setupSpec() {
        filesUnderFolder1 = []
        filesUnderFolder2 = []

        new File('folder1').eachFileRecurse {
            filesUnderFolder1 << it
        }
        new File('folder2').eachFileRecurse {
            filesUnderFolder2 << it
        }
    }

    void "test validate file #filesUnderTest under folder1"() {
        when:
        validateFile(filesUnderTest)

        then:
        notThrown(Exception)

        where:
        filesUnderTest << filesUnderFolder1
    }

    void "test validate file #filesUnderTest under folder2"() {
        when:
        validateFile(filesUnderTest)

        then:
        thrown(Exception)

        where:
        filesUnderTest << filesUnderFolder2
    }

    // Mimic validateFile method call
    private validateFile(File file) {
        if ( !file.name.startsWith( 'a' ) ) {
            throw new Exception()
        }
    }
}

Upvotes: 1

Peter Niederwieser
Peter Niederwieser

Reputation: 123950

@Unroll
def "validate #folder"() { ... }

Upvotes: 2

Opal
Opal

Reputation: 84834

I see no good solutions here.

notThrown method does not return any result with additional information and in my opinion this isn't a case of bad design because the purpose of this method is to validate the result of specification without possibility of any further action.

To be honest I think that adding a detailed message to exception being thrown the best idea. Without this message, the exception being thrown seems pointless. With some details You can easily determine what happened not only inside the test but in the real system as well.

You can also add println statement inside eachFileRecurse closure. but this obviously a bad idea.

Upvotes: 1

Related Questions