Setting up a new spring boot java project using groovy Spock unit tests in IntelliJ IDEA. I cannot get my first unit test to run. I created it from inside IntelliJ and it is under src/test/groovy.
Here is the unit test.
package com.heavyweightsoftware.orders.pojo
import com.heavyweightsoftware.util.FixedDecimal
import spock.lang.Specification
class ItemOrderedTest extends Specification {
public static final String ITEM_ID = "OU812"
public static final String ITEM_NAME = "Eddie V."
public static final int ITEM_QUANTITY = 5
public static final FixedDecimal ITEM_UNIT_PRICE = new FixedDecimal(35.62, 2)
static ItemOrdered getItemOrdered() {
ItemOrdered result = new ItemOrdered()
result.itemId = ITEM_ID
result.quantity = ITEM_QUANTITY
result.itemName = ITEM_NAME
result.unitPrice = ITEM_UNIT_PRICE
return result;
}
def "GetQuantity"() {
given: "A test item"
ItemOrdered testItem = getItemOrdered()
when: "Getting Value"
int result = testItem.quantity
then: "Should be correct"
result == ITEM_QUANTITY
}
def "GetItemId"() {
given: "A test item"
ItemOrdered testItem = getItemOrdered()
when: "Getting Value"
String result = testItem.itemId
then: "Should be correct"
result == ITEM_ID
}
def "GetItemName"() {
given: "A test item"
ItemOrdered testItem = getItemOrdered()
when: "Getting Value"
String result = testItem.itemName
then: "Should be correct"
result == ITEM_NAME
}
def "GetLineTotal"() {
given: "A test item"
ItemOrdered testItem = getItemOrdered()
when: "Getting Total"
FixedDecimal result = testItem.lineTotal
then: "Should be correct"
FixedDecimal total = new FixedDecimal(178.10, 2)
result == total
}
def "GetUnitPrice"() {
given: "A test item"
ItemOrdered testItem = getItemOrdered()
when: "Getting Value"
FixedDecimal result = testItem.unitPrice
then: "Should be correct"
result == ITEM_UNIT_PRICE
}
}
Here is the output from when I click on the double arrow in IntelliJ to run the full unit test...
Testing started at 12:47 PM ...
Starting Gradle Daemon...
Connected to the target VM, address: '127.0.0.1:33391', transport: 'socket'
Gradle Daemon started in 621 ms
> Task :compileJava UP-TO-DATE
> Task :processResources UP-TO-DATE
> Task :classes UP-TO-DATE
> Task :compileTestJava UP-TO-DATE
> Task :processTestResources NO-SOURCE
> Task :testClasses UP-TO-DATE
> Task :test FAILED
FAILURE: Build failed with an exception.
* What went wrong:
Execution failed for task ':test'.
> No tests found for given includes: [com.heavyweightsoftware.orders.pojo.ItemOrderedTest](filter.includeTestsMatching)
* Try:
Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output. Run with --scan to get full insights.
* Get more help at https://help.gradle.org
Deprecated Gradle features were used in this build, making it incompatible with Gradle 7.0.
Use '--warning-mode all' to show the individual deprecation warnings.
See https://docs.gradle.org/6.6.1/userguide/command_line_interface.html#sec:command_line_warnings
BUILD FAILED in 4s
4 actionable tasks: 1 executed, 3 up-to-date
Disconnected from the target VM, address: '127.0.0.1:33391', transport: 'socket'
and a screenshot of the test setup:
Here is my build.gradle file:
plugins {
id 'org.springframework.boot' version '2.3.4.RELEASE'
id 'io.spring.dependency-management' version '1.0.10.RELEASE'
id 'java'
}
group = 'com.heavyweightsoftware'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = '11'
repositories {
mavenCentral()
// for heavyweight software dependencies
flatDir {
dirs 'libs'
}
// Spock snapshots are available from the Sonatype OSS snapshot repository
maven { url "https://oss.sonatype.org/content/repositories/snapshots/" }
}
dependencies {
// heavyweight software libraries
compile fileTree(dir: 'libs', include: ['*.jar'])
runtimeOnly 'com.h2database:h2'
runtimeOnly 'mysql:mysql-connector-java'
// mandatory dependencies for using Spock
compile "org.codehaus.groovy:groovy-all:3.0.5"
testImplementation platform("org.spockframework:spock-bom:2.0-M1-groovy-2.5")
testImplementation "org.spockframework:spock-core"
testImplementation "org.spockframework:spock-junit4" // you can remove this if your code does not rely on old JUnit 4 rules
// optional dependencies for using Spock
testImplementation "org.hamcrest:hamcrest-core:1.3" // only necessary if Hamcrest matchers are used
testImplementation "net.bytebuddy:byte-buddy:1.9.3" // allows mocking of classes (in addition to interfaces)
testImplementation "org.objenesis:objenesis:2.6" // allows mocking of classes without default constructor (together with CGLIB)
// spring dependencies
implementation (
'org.springframework.boot:spring-boot-configuration-processor',
'org.springframework.boot:spring-boot-starter-data-jpa',
'org.springframework.boot:spring-boot-starter-web',
)
testImplementation('org.springframework.boot:spring-boot-starter-test') {
exclude group: 'org.junit.vintage', module: 'junit-vintage-engine'
}
}
test {
useJUnitPlatform()
}
I have attempted to find all of the issues related to this, but none of them seemed to help. It doesn't seem to be finding my source code of the unit test.
As we can see, Spock has more readability and a clearer documented code, it does not need 3rd parties, and it is more powerful than JUnit. In the end, using Spock or JUnit or TestNG or anything else is absolutely up to you. They each have their pros and cons for sure.
Similar to any other Unit testing frameworks, Spock too can be used to write scenarios/test cases for an application under test. We’ll try to compare and contrast the different features of the Spock framework with the existing/known frameworks like JUnit. Let us first try to understand the Groovy’s “def” keyword in brief.
Adding Spring Boot Test In order to use the testing utilities of Spring Boot Test, we need the following dependency: 3.3. Setting up Groovy And since Spock is based on Groovy, we have to add and configure the gmavenplus-plugin as well to be able to use this language in our tests:
Adding the Spock Framework Dependencies with Spring Support For Spock itself and for the Spring support we need two dependencies: Notice, that the versions are specified with are a reference to the used groovy version. 3.2. Adding Spring Boot Test In order to use the testing utilities of Spring Boot Test, we need the following dependency: 3.3.
After some quick googling it turned out that the stable version of Spock (1.3) uses JUnit 4 under the hood, but new Spring Boot comes with JUnit 5. To keep things backwards compatible JUnit team has provided JUnit Vintage engine which allows running JUnit 4 tests on JUnit 5 platform and it looked like it should do the job.
Disclaimer: I am a 100% Maven user. Gradle for me is more like trial & error. But I am interested in Spock questions, so I am giving it a shot.
You need to add the Groovy plugin to your build file:
plugins {
// ...
id 'java'
id 'groovy'
}
This will also help IDEA to recognise that this is a Groovy project and you can run tests from src/test/groovy
.
Next, you will get test compilation errors because there is an obvious mismatch between you using
org.spockframework:spock-bom:2.0-M1-groovy-2.5
vs.org.codehaus.groovy:groovy-all:3.0.5
,i.e.
So either you downgrade Groovy or upgrade Spock. Besides, M1 is not up to date, better use M3.
// mandatory dependencies for using Spock
testCompile "org.codehaus.groovy:groovy:2.5.13"
testImplementation platform("org.spockframework:spock-bom:2.0-M3-groovy-2.5")
Now your test should compile and run. I did not check the test as such, though. I cannot run it anyway without the classes under test.
Getting rid of the org.spockframework:spock-junit4
dependency is optional. As was said before, Spock 2.x is based on JUnit 5, so if you do not have any legacy Spock tests in your project using JUnit 4 features like @RunWith
for PowerMock or similar ugly stuff, you do not need it.
Maybe you want to change your build file to be more similar to the one in the Spock sample project.
Update 2021-07-20: I just opened theis example project again in order to answer another question. In doing do, I noticed that you need to be careful when using something like sourceCompatibility = '11'
, but running the build on an older JDK like 8. It will cause the following, counter-intuitive Gradle error:
Execution failed for task ':test'.
> No tests found for given includes: [com.heavyweightsoftware.orders.pojo.ItemOrderedTest](filter.includeTestsMatching)
* Try:
Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output. Run with --scan to get full insights.
Only when running the test with Gradle parameter --debug
, you will see the root cause (log labels and timestamps deleted):
Gradle Test Executor 31 FAILED
org.gradle.api.internal.tasks.testing.TestSuiteExecutionException: Could not execute test class 'com.heavyweightsoftware.orders.pojo.ItemOrderedTest'.
at org.gradle.api.internal.tasks.testing.SuiteTestClassProcessor.processTestClass(SuiteTestClassProcessor.java:53)
(...)
Caused by:
java.lang.UnsupportedClassVersionError: com/heavyweightsoftware/orders/pojo/ItemOrderedTest has been compiled by a more recent version of the Java Runtime (class file version 55.0), this version of the Java Runtime only recognizes class file versions up to 52.0
at java.lang.ClassLoader.defineClass1(Native Method)
(...)
For me worked this solution. Just remove:
test {
useJUnitPlatform()
}
Here is my build.gradle:
plugins {
id 'java'
id 'groovy'
id 'org.springframework.boot' version '2.4.3'
id 'io.spring.dependency-management' version '1.0.11.RELEASE'
id 'org.yourcompany.common.dataflow.plugin' version '0.1.13'
id 'com.github.jk1.dependency-license-report' version '1.16'
}
group = 'org.yourcompany.dataflow'
version = '0.0.1'
sourceCompatibility = '11'
configurations {
compileOnly {
extendsFrom annotationProcessor
}
}
repositories {
maven {
url "http://nexus.yourcompany.ru:8081/repository/maven-public/"
}
}
ext {
set('springCloudVersion', "2020.0.1")
}
dependencies {
implementation 'org.springframework.cloud:spring-cloud-stream'
implementation 'org.springframework.cloud:spring-cloud-stream-binder-kafka'
implementation 'org.springframework.boot:spring-boot-starter-web'
implementation 'org.springframework.boot:spring-boot-starter-actuator'
implementation 'org.springframework.kafka:spring-kafka'
// third party
compile 'io.dgraph:dgraph4j:20.11.0'
// yourcompany
implementation 'org.yourcompany:common_dataflow_annotations:0.1.11'
implementation('org.yourcompany:common_service:0.2.27') {
exclude group: 'io.springfox', module: 'springfox-swagger2'
}
// test and dev
testCompile group: 'org.codehaus.groovy', name: 'groovy-all', version: '2.5.6'
testImplementation group: 'org.spockframework', name: 'spock-core', version: '1.3-groovy-2.5'
testImplementation group: 'org.spockframework', name: 'spock-spring', version: '1.3-groovy-2.5'
developmentOnly 'org.springframework.boot:spring-boot-devtools'
annotationProcessor 'org.springframework.boot:spring-boot-configuration-processor'
annotationProcessor 'org.projectlombok:lombok'
compileOnly 'org.projectlombok:lombok'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
testImplementation 'org.springframework.kafka:spring-kafka-test'
}
dependencyManagement {
imports {
mavenBom "org.springframework.cloud:spring-cloud-dependencies:${springCloudVersion}"
}
}
Adding the following works for me like Alex mentioned above.
test {
useJUnitPlatform()
}
dependencies {
compile 'org.codehaus.groovy:groovy-all:3.0.8'
testCompile 'org.spockframework:spock-core:2.0-groovy-3.0'
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With