Java Integration Test No Runnable Methods error - Spring Runner - java

I am trying to write my first integration test. JUnit tests are working fine.
Here is my WebControllerIT.java which is the corresponding integration test for my WebController class:
package com.socialinteraction.componenttests;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;
import com.socialinteraction.SocialInteractionApplication;
import com.socialinteraction.WebController;
import com.socialinteraction.database.repositories.AppUserRepository;
import org.junit.jupiter.api.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.web.server.LocalServerPort;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpMethod;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.web.client.RestTemplate;
#RunWith(SpringRunner.class)
#SpringBootTest(
classes = SocialInteractionApplication.class,
webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
public class WebControllerIT {
#LocalServerPort private int webServerPort;
#Autowired private AppUserRepository AppUserRepository;
#Autowired private WebController webController;
private RestTemplate restTemplate = new RestTemplate();
private String createURLWithPort(String uri) {
return "http://localhost:" + webServerPort + uri;
}
#Test
public void testSetNewAppUser() {
assertTrue(true);
assertTrue(false);
}
}
I am trying to troubleshoot why my Integration Test is not working, hence the simple assertTrue() methods.
I am currently getting a java.lang.Exception: No runnable methods, when I try and run the test class, that test method of the new integrationTest Gradle task I created.
Here is my package structure for context:
Lastly, here is my build.gradle file:
plugins {
id 'org.springframework.boot' version '2.2.5.RELEASE'
id 'io.spring.dependency-management' version '1.0.9.RELEASE'
id 'java'
}
group = 'com.socialinteraction'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = '1.8'
configurations {
compileOnly {
extendsFrom annotationProcessor
}
integrationTestCompile.extendsFrom testCompile
integrationTestRuntime.extendsFrom testRuntime
integrationTestImplementation.extendsFrom testImplementation
}
repositories {
mavenCentral()
}
sourceSets {
integrationTest {
java {
compileClasspath += main.output + test.output
runtimeClasspath += main.output + test.output
srcDir file('src/integration-test/java')
}
resources.srcDir file('src/integration-test/resources')
}
}
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-data-mongodb'
implementation 'org.springframework.boot:spring-boot-starter-web'
compileOnly 'org.projectlombok:lombok'
annotationProcessor 'org.projectlombok:lombok'
testImplementation('org.springframework.boot:spring-boot-starter-test') {
exclude group: 'org.junit.vintage', module: 'junit-vintage-engine'
}
testImplementation('org.junit.jupiter:junit-jupiter-api:5.4.2')
testRuntime('org.junit.jupiter:junit-jupiter-engine:5.4.2')
// testCompile "org.powermock:powermock-module-junit4:1.6.4"
// testCompile 'org.mockito:mockito-core:2.7.22'
implementation 'org.jetbrains:annotations:15.0'
implementation 'junit:junit:4.12'
implementation 'org.testng:testng:6.9.6'
implementation 'junit:junit:4.12'
implementation 'junit:junit:4.12'
implementation 'org.testng:testng:6.9.6'
integrationTestCompile 'org.assertj:assertj-core:3.0.0'
}
test {
useJUnitPlatform()
}
task integrationTest(type: Test) {
testClassesDirs = sourceSets.integrationTest.output.classesDirs
classpath = sourceSets.integrationTest.runtimeClasspath
}
check.dependsOn integrationTest
integrationTest.mustRunAfter test
Any ideas why I cannot run my integration tests? Any input would be helpful, thank you!

I'm not sure but probably you are mixing junit4 with junit5. Try using this dependencies:
testImplementation('org.springframework.boot:spring-boot-starter-test') {
exclude group: 'org.junit.vintage', module: 'junit-vintage-engine'
}
testImplementation 'org.junit.jupiter:junit-jupiter-api'
And remove all junit, assertJ, testing dependencies
Then replace #RunWith(SpringRunner.class) with #ExtendWith(SpringExtension.class)
And classes = SocialInteractionApplication.class is probably not needed in that case.

Related

Caused by: java.lang.ClassNotFoundException: DemoApplication

I created a new Spring application from https://start.srping.io
My build.gradle
plugins {
id 'java'
id 'org.springframework.boot' version '2.7.5'
id 'io.spring.dependency-management' version '1.0.15.RELEASE'
}
group = 'com.example'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = '19'
repositories {
mavenCentral()
}
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
implementation 'org.springframework.boot:spring-boot-starter-security'
implementation 'org.springframework.boot:spring-boot-starter-web'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
testImplementation 'org.springframework.security:spring-security-test'
}
tasks.named('test') {
useJUnitPlatform()
}
File DemoApplication.java
package com.example.demo;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
#SpringBootApplication
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
}
I press button Run, the program error. How to fix it?
Looks like project dependencies mentioned in build.gradle file not downloaded properly because I can see some compilation errors as well.
Please run this command and try again.
gradle build

build.gradle cannot resolve symbol 'groovy.json.JsonSlurper'

I can't resolve the groovy.json.JsonSlurper in the build.gradle file with Intellij, does anyone know how to fix it?
plugins {
id 'java'
}
group 'org.example'
version '1.0-SNAPSHOT'
repositories {
mavenCentral()
}
dependencies {
testImplementation 'org.junit.jupiter:junit-jupiter-api:5.8.1'
testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.8.1'
}
test {
useJUnitPlatform()
}
task sample() {
doLast {
sample();
}
}
import groovy.json.JsonSlurper
def sample(){
def json = new JsonSlurper().parseText('{"a":"b"}')
println(json);
}
You missing the needed dependency.
Add org.codehaus.groovy:groovy-json:3.0.9 in dependencies section so ti will look like
dependencies {
testImplementation 'org.junit.jupiter:junit-jupiter-api:5.8.1'
testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.8.1'
implementation 'org.codehaus.groovy:groovy-json:3.0.9'
}
And then you can test with CLI as gradle sample or ./gradlew sample and it will return {a=b}

Getting a ClassNotFound exception when using mongotemplate

I am getting the following exception when running a spring boot application that uses the mongo template:
Caused by: java.lang.ClassNotFoundException: org.springframework.data.mongodb.MongoDatabaseFactory
This is the main code:
package com.example.redismongo.mongodb;
import com.mongodb.client.MongoClient;
import com.mongodb.client.MongoClients;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.data.mongodb.config.EnableMongoAuditing;
import org.springframework.data.mongodb.core.MongoTemplate;
#Configuration
#EnableMongoAuditing
public class MongoConfiguration {
#Bean
public MongoClient mongo(){
return MongoClients.create("mongodb://localhost:27017");
}
#Primary
#Bean(name = "mongoTemplate")
public MongoTemplate mongoTemplate(){
return new MongoTemplate(mongo(), "test");
}
}
plugins {
id 'org.springframework.boot' version '2.4.2'
id 'io.spring.dependency-management' version '1.0.11.RELEASE'
id 'java'
}
group = 'com.example'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = '11'
repositories {
mavenCentral()
}
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-web'
implementation group: 'org.springframework.data', name: 'spring-data-commons', version: '2.2.8.RELEASE'
implementation group: 'org.springframework.data', name: 'spring-data-mongodb', version: '2.2.8.RELEASE'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
}
test {
useJUnitPlatform()
}
I need to test the 2.2.8 version as that is the version that is being used at work. I am trying to test some of its functionality in my pc to test certain fail scenarios. How can I make 2.2.8 work?
Try adding spring-boot-starter-data-mongodb instead of spring-data-mongodb.

JOOQ Doesn't Generate

I was following here. I used postgresql instead of h2. I was able to build the project with some additional fields.
I created a package database under com.example.demo, but it was still empty after project was built.
build.gradle:
buildscript {
ext {
springBootVersion = '2.4.2'
}
repositories {
mavenLocal()
mavenCentral()
}
dependencies {
classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}")
classpath 'org.jooq:jooq-codegen:3.14.4'
classpath 'org.postgresql:postgresql:42.2.18'
}
}
apply plugin: 'java'
apply plugin: 'org.springframework.boot'
apply plugin: 'io.spring.dependency-management'
group = 'com.example'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = '15'
repositories {
mavenLocal()
mavenCentral()
}
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
implementation 'org.springframework.boot:spring-boot-starter-jdbc'
implementation 'org.springframework.boot:spring-boot-starter-jooq'
implementation 'org.springframework.boot:spring-boot-starter-web'
implementation 'org.flywaydb:flyway-core'
runtimeOnly 'org.postgresql:postgresql'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
}
test {
useJUnitPlatform()
}
import org.jooq.codegen.GenerationTool
import org.jooq.meta.jaxb.*
task generate {
def configuration = new Configuration()
configuration
.withJdbc(new Jdbc()
.withDriver('org.postgresql.Driver')
.withUrl('jdbc:postgresql://localhost:5432/vertx')
.withUser('postgres')
.withPassword('postgres'))
.withGenerator(new Generator()
.withDatabase(new Database().withInputSchema('public'))
.withGenerate(new Generate()
.withPojos(true)
.withDaos(true))
.withTarget(new Target()
.withPackageName('com.example.demo.database')
.withDirectory('src/main/java')))
doLast {
GenerationTool.generate(configuration)
}
}
Is there something I am missing? Why can I not see pojos and daos in database package? My database has only one table with 2 columns.
BUILD SUCCESSFULL when I type ./gradlew generate, but nothing gets generated.
You can try ./gradlew generate --info command, which will give you more information about the build process.
My gradle script is quite similar to yours. By using above command, I find out that the classes are actually generated, but in a different folder /Users/{MyUserName}/.gradle/daemon/7.1.1/src/main/java.
So I have to explicitly set the output directory with def outputDirectory = projectDir.toString() + '/src/main/java'.
This works for me
buildscript {
repositories {
mavenLocal()
mavenCentral()
}
dependencies {
classpath 'org.jooq:jooq-codegen:3.16.2'
classpath 'mysql:mysql-connector-java:8.0.27'
}
}
plugins {
id 'org.springframework.boot' version '2.6.2'
id 'io.spring.dependency-management' version '1.0.11.RELEASE'
id 'java'
}
if(JavaVersion.current() != JavaVersion.VERSION_11){
throw new GradleException("This build must be run with java 11")
}
repositories {
mavenCentral()
}
group = 'snorlax'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = '11'
//create a fat Jar with all dependencies
jar {
duplicatesStrategy(DuplicatesStrategy.EXCLUDE)
from {
configurations.compileClasspath.collect { it.isDirectory() ? it : zipTree(it) }
}
manifest {
attributes "Main-Class": "com.snorlax.userservice.MainApplication"
}
}
configurations {
compileOnly {
extendsFrom annotationProcessor
}
}
dependencies {
// Spring boot
implementation 'org.springframework.boot:spring-boot-starter-actuator'
implementation 'org.springframework.boot:spring-boot-starter-web'
developmentOnly 'org.springframework.boot:spring-boot-devtools'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
// Swagger
implementation group: 'io.springfox', name: 'springfox-swagger2', version: '2.9.2'
implementation group: 'io.springfox', name: 'springfox-swagger-ui', version: '2.9.2'
// Lombok
compileOnly 'org.projectlombok:lombok'
annotationProcessor 'org.projectlombok:lombok'
// RDS Connection
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
runtimeOnly 'mysql:mysql-connector-java:8.0.27'
// AWS secretes manager
implementation 'com.amazonaws.secretsmanager:aws-secretsmanager-jdbc:1.0.6'
// JOOQ
implementation 'org.springframework.boot:spring-boot-starter-jooq'
implementation 'org.jooq:jooq-meta:3.16.2'
compileOnly 'org.jooq:jooq-codegen:3.16.2'
}
test {
useJUnitPlatform()
}
/************************
jooq code generation
*************************/
import org.jooq.codegen.GenerationTool;
import org.jooq.meta.jaxb.*;
task generate {
def outputDirectory = projectDir.toString() + '/src/main/java'
def configuration = new Configuration()
.withJdbc(new Jdbc()
.withDriver('com.mysql.cj.jdbc.Driver')
.withUrl('jdbc:mysql://127.0.0.1:3306/snorlaxRds')
.withUser('root')
.withPassword('123456'))
.withGenerator(new Generator()
.withDatabase(new Database().withInputSchema("snorlaxRds"))
.withGenerate(new Generate()
.withPojos(true)
.withDaos(true))
.withTarget(new Target()
.withPackageName('snorlax.userservice.database')
.withDirectory(outputDirectory)));
doLast {
GenerationTool.generate(configuration)
}
}
Your file looks okay. I had a similar issue (while using maven). Try three things (that worked for me):
check case of the schema in "withInputSchema" property. Try to pass uppercase PUBLIC.
try to change 'src/main/java' to './src/main/java'
add "includes" and pass .* in it (to generate for all tables in the schema)

Integration test and build.gradle Java Spring

I am trying to write integration tests for my service.
I have tried to write a simple test as my first test. My WebControllerIT class is as follows:
#RunWith(SpringRunner.class)
#SpringBootTest(
classes = SocialInteractionApplication.class,
webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
public class WebControllerIT {
#LocalServerPort private int webServerPort;
#Autowired private AppUserRepository AppUserRepository;
#Autowired private WebController webController;
private RestTemplate restTemplate = new RestTemplate();
private String createURLWithPort(String uri) {
return "http://localhost:" + webServerPort + uri;
}
#Test
public void testSetNewAppUser() {
HttpEntity<String> entity = new HttpEntity<String>(null,null);
ResponseEntity<String> response =
restTemplate.exchange(
createURLWithPort("/{RobsAndroid}/setNewAppUser/{Rob}"),
HttpMethod.GET,
entity,
String.class);
String expected = "New AppUser: " + "RobsAndroid"+ " set OK.";
assertEquals(expected,response.getBody());
assertEquals(HttpStatus.OK,response.getStatusCode());
}
}
However, I am getting an error:
Execution failed for task ':integrationTest'.
> No tests found for given includes: [com.socialinteraction.componenttests.WebControllerIT.testSetNewAppUser](filter.includeTestsMatching)
I can't seem to work out what's going on, any ideas?
To give some more context, I wasn't sure how to start with component testing. This included: where they should be located, what dependencies they should have, how to run them in the gradle build etc. I followed a tutorial and my build.gradle file has ended up as follows:
plugins {
id 'org.springframework.boot' version '2.2.5.RELEASE'
id 'io.spring.dependency-management' version '1.0.9.RELEASE'
id 'java'
}
group = 'com.socialinteraction'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = '1.8'
configurations {
compileOnly {
extendsFrom annotationProcessor
}
}
repositories {
mavenCentral()
}
sourceSets {
integrationTest {
java {
compileClasspath += main.output + test.output
runtimeClasspath += main.output + test.output
srcDir file('src/integration-test/java')
}
resources.srcDir file('src/integration-test/resources')
}
}
configurations {
integrationTestCompile.extendsFrom testCompile
integrationTestRuntime.extendsFrom testRuntime
integrationTestImplementation.extendsFrom testImplementation
}
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-data-mongodb'
implementation 'org.springframework.boot:spring-boot-starter-web'
compileOnly 'org.projectlombok:lombok'
annotationProcessor 'org.projectlombok:lombok'
testImplementation('org.springframework.boot:spring-boot-starter-test') {
exclude group: 'org.junit.vintage', module: 'junit-vintage-engine'
}
testImplementation('org.junit.jupiter:junit-jupiter-api:5.4.2')
testRuntime('org.junit.jupiter:junit-jupiter-engine:5.4.2')
// testCompile "org.powermock:powermock-module-junit4:1.6.4"
// testCompile 'org.mockito:mockito-core:2.7.22'
implementation 'org.jetbrains:annotations:15.0'
implementation 'junit:junit:4.12'
implementation 'org.testng:testng:6.9.6'
implementation 'junit:junit:4.12'
implementation 'junit:junit:4.12'
implementation 'org.testng:testng:6.9.6'
}
test {
useJUnitPlatform()
}
task integrationTest(type: Test) {
testClassesDirs = sourceSets.integrationTest.output.classesDirs
classpath = sourceSets.integrationTest.runtimeClasspath
}
check.dependsOn integrationTest
integrationTest.mustRunAfter test
I essentially made sure the integration test dependencies were inherited from unit tests, there was a new intergrationTest type and that this was ran in the build after unit tests.
Side question - not sure testRuntime, testImplementation and other dependencies type are all needed/right, so a good link to explain these would be great if someone has one?
Thanks so much for your help!
try to add useJUnitPlatform() inside your task desc:
task integrationTest(type: Test) {
useJUnitPlatform()
testClassesDirs = sourceSets.integrationTest.output.classesDirs
classpath = sourceSets.integrationTest.runtimeClasspath
}
It works for me.

Categories

Resources