I started playing around with Spock testing framework and my build.gradle
dependencies section looks like this:
dependencies {
testCompile "org.spockframework:spock-core:1.3-groovy-2.5"
}
I have a (useless) Spock test that requires creation of a stub:
def 'A test that will fail'() {
given: ''
def random = Stub(Random)
}
When launched, the test fails with the given error:
CannotCreateMockException: Cannot create mock for class java.util.Random. Mocking of non-interface types requires a code generation library. Please put an up-to-date version of byte-buddy or cglib-nodep on the class path.
This error is mentioned in Spock documentation and it's caused by cglib or byte-buddy not being available at runtime.
Considering that spock-core's pom lists both byte-buddy and cglib as compile dependencies, why are they not retained at runtime? In other words, why do we need to explicitly add the following runtime dependency to our build.gradle file?
testRuntime "net.bytebuddy:byte-buddy:1.9.3"
Because both (byte-buddy and cglib-nodep) are marked as <optional>true</optional>
, where from Gradle point of view they are as compileOnly
dependencies - see: https://blog.gradle.org/introducing-compile-only-dependencies
Compile-only dependencies are distinctly different than regular compile dependencies. They are not included on the runtime classpath and they are non-transitive, meaning they are not included in dependent projects.