Does Spock have Test Event Listeners
Asked Answered
S

2

5

Does spock has any Test event listener like how TestNg has ITestListener. ?

So that I can have access, when the test cases failed etc.

Senator answered 22/9, 2014 at 5:34 Comment(3)
I've never seen any listener in spock.Unroll
Mention your purpose to do thatCeja
Spock does have this feature and I answered this in another thread here. https://mcmap.net/q/1891428/-is-it-possible-to-log-spock-feature-method-names-and-clause-labels Check if that helpsPhotography
C
7

Spock does have listeners. Unfortunately the official documentation, which is otherwise excellent, has "TODO" under Writing Custom Extensions: http://spockframework.github.io/spock/docs/1.0/extensions.html.

Update: The official docs have been updated to include helpful information about custom extensions: http://spockframework.org/spock/docs/1.1/extensions.html. See those for more details.

There are two ways: Annotation-based and Global.

Annotation-based

Three pieces here: the annotation, the extension, and the listener.

The annotation:

    import java.lang.annotation.*
    import org.spockframework.runtime.extension.ExtensionAnnotation

    @Retention(RetentionPolicy.RUNTIME)
    @Target([ElementType.TYPE, ElementType.METHOD])
    @ExtensionAnnotation(ListenForErrorsExtension)
    @interface ListenForErrors {}

The extension (Updated):

    import org.spockframework.runtime.extension.AbstractAnnotationDrivenExtension
    import org.spockframework.runtime.model.SpecInfo

    class ListenForErrorsExtension extends AbstractAnnotationDrivenExtension<ListenForErrors> {
        void visitSpec(SpecInfo spec) {
            spec.addListener(new ListenForErrorsListener())
        }

       @Override
       void visitSpecAnnotation(ListenForErrors annotation, SpecInfo spec){
        println "do whatever you need here if you do. This method will throw an error unless you override it"
    }
    }

The listener:

    import org.spockframework.runtime.AbstractRunListener
    import org.spockframework.runtime.model.ErrorInfo

    class ListenForErrorsListener extends AbstractRunListener {
        void error(ErrorInfo error) {
            println "Test failed: ${error.method.name}"
            // Do other handling here
        }
    }

You can then use your new annotation on a Spec class or method:

    @ListenForErrors
    class MySpec extends Specification {
        ...
    }

Global

This also has three pieces: the extension, the listener, and the registration.

    class ListenForErrorsExtension implements IGlobalExtension {
        void visitSpec(SpecInfo specInfo) {
            specInfo.addListener(new ListenForErrorsListener())
        }
    }

You can use the same ListenForErrorsListener class as above.

To register the extension, create a file named org.spockframework.runtime.extension.IGlobalExtension in the META-INF/services directory. If using Gradle/Maven, this will be under src/test/resources. This file should contain only the fully qualified class name of your global extension, for example:

com.example.tests.ListenForErrorsExtension

References

For examples, see the Spock built-in extensions here: https://github.com/spockframework/spock/tree/groovy-1.8/spock-core/src/main/java/spock/lang https://github.com/spockframework/spock/tree/groovy-1.8/spock-core/src/main/java/org/spockframework/runtime/extension/builtin

Comras answered 14/8, 2016 at 3:2 Comment(1)
Hi, I do everything like described in "Annotation-based" section but when I execute my annotated specification I get such exception: "org.spockframework.runtime.InvalidSpecException: @ListenForErrors may not be applied to Specs".Extraterrestrial
A
0

Spock has interaction listening via Mock:

def "should send messages to all subscribers"() {
    given:
    def subscriber = Mock(Subscriber)

    when:
    publisher.send("hello")

    then:
    1 * subscriber.receive("hello")
}

See the interaction based testing in the docs

Anodyne answered 15/1, 2015 at 9:50 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.