Spock 2¶
There is no special extensions for Spock 2 (like it was for spock 1), instead I did an extra integration library, so you can use existing Junit 5 extensions with spock.
Note
You are not limited to guicey junit 5 extensions, you can use (almost) any junit 5 extensions. And you can use any other spock extensions together with junit extensions.
Setup¶
You will need the following dependencies (assuming BOM used for versions management):
testImplementation 'ru.vyarus:spock-junit5'
testImplementation 'org.spockframework:spock-core:2.3-groovy-4.0'
testImplementation 'io.dropwizard:dropwizard-testing'
testImplementation 'org.junit.jupiter:junit-jupiter-api'
Usage¶
See junit 5 extensions docs for usage details (it's all used the same).
Warning
Junit 5 extensions would not work with @Shared
spock fields! You can still use
such fields directly, but don't expect junit 5 extensions to be able to work with such fields (they can't "see" it).
Here is a simple example:
@TestDropwizardApp(App)
class MyTest extends Specification {
@Inject MyService service
def "Check something" (ClientSupport client) {
when: "calling rest endpoint"
def res = client.targetRest("foo/bar").request()
.buildGet().invoke().readEntity(String)
then: "result correct"
res == "something"
and: "service called"
service.isCalled()
}
}
Tip
Note that parameter injection will also work in test and fixture (setup/cleanup) methods
Overall, you get best of both worlds: same extensions as in junit 5 (and ability to use all other junit extensions) and spock expressiveness for writing tests.
Special cases¶
Junit 5 doc describes system stubs library usage. It is completely valid for spock, I'll just show a few examples here on how to:
- Modify (and reset) environment variables
- Modify (and reset) system properties
- Validate system output (e.g. testing logs)
- Intercepting system exit
@ExtendWith(SystemStubsExtension)
class StartupErrorTest extends Specification {
@SystemStub
SystemExit exit
@SystemStub
SystemErr err
def "Check app crash"() {
when: "starting app"
exit.execute(() -> {
new App().run(['server'] as String[])
});
then: "error"
exit.exitCode == 1
err.text.contains("Error message text")
}
}
@ExtendWith(SystemStubsExtension)
class EnvironmentChangeTest extends Specification {
@SystemStub
EnvironmentVariables ENV
@SystemStub
SystemOut out
@SystemStub
SystemProperties propsReset
def "Check variables mapping"() {
setup:
ENV.set("VAR", "1")
System.setProperty("foo", "bar") // OR propsReset.set("foo", "bar") - both works the same
when:
// something requiring custom env or property values
then:
// validate system output (e.g. logs correctness)
out.text.contains("Some message assumed to be logged")
Note
Use test framework-agnostic utilities to run application with configuration or to run application without web part (for faster test).