0

I've set up integration tests for testing my API and I want my tests to pick up settings from application.yml. The trouble is that my test class never reads the value of ${base-urls.test-url} from the properties file. I've tried using @ContextConfiguration, @TestPropertySource, @PropertySource and @RunWith(SpringRunner.class) without success.

How can I get my integration test to read the properties file?

My project directories look like this:

|____src
| |____test
| | |____resources
| | |____java
| | | |____org
| | | | |____example
| | | | | |____forex
| | | | | | |____controller
| | | | | | | |____CurrencyControllerTest.java
| | | | | | |____service
| | | | | | | |____CurrencyServiceTest.java
| |____integrationTest
| | |____resources
| | | |____application.yml
| | |____java
| | | |____org
| | | | |____example
| | | | | |____forex
| | | | | | |____integration
| | | | | | | |____ApiTests.java
| | | | | | |____domain
| | | | | | | |____CurrencyHelper.java
| |____main
| | |____resources
| | | |____application.yml
| | |____java
| | | |____org
| | | | |____example
| | | | | |____Application.java
| | | | | |____forex
| | | | | | |____repository
| | | | | | | |____CurrencyRepository.java
| | | | | | |____controller
| | | | | | | |____CurrencyController.java
| | | | | | |____service
| | | | | | | |____CurrencyService.java
| | | | | | |____domain
| | | | | | | |____Currency.java

I have an application resource file, src/integrationTest/resources/application.yml and also tried placing it in the same package as ApiTests class. The file contains this:

base-urls:
  test-url: ${TEST_URL:http://localhost:8080}

The set up is that I want to have a running application, then run my integration tests with the URL from the @Value annotation. My test class uses Rest Assured and looks like this:

public class ApiTests {

    @Value("${base-urls.test-url}")
    private String baseUrl;

    private Currency dummy;

    @Before
    public void setup() {
        RestAssured.baseURI = baseUrl;
        dummy = CurrencyHelper.dummy();
    }

My build.gradle file looks like this:

plugins {
    id 'java'
    id 'application'
    id 'io.spring.dependency-management' version '1.0.7.RELEASE'
    id 'org.springframework.boot' version '2.3.4.RELEASE'
}

apply plugin: 'java'
apply plugin: 'application'
apply plugin: 'io.spring.dependency-management'
apply plugin: 'org.springframework.boot'

group 'org.example.forex'
version '1.0-SNAPSHOT'
sourceCompatibility = '1.8'
mainClassName = 'org.example.Application'

sourceSets {
    integrationTest {
        resources {
            srcDir 'src/integrationTest/resources'
        }
        compileClasspath += sourceSets.main.output + configurations.testRuntime
        runtimeClasspath += output + compileClasspath
    }
}

def versions = [
        postgresql         : '42.2.2'
]

repositories {
    mavenCentral()
}

dependencies {
    implementation "org.springframework.boot:spring-boot-starter"
    implementation "org.springframework.boot:spring-boot-starter-web"
    implementation'org.springframework.boot:spring-boot-starter-data-jpa'
    implementation "org.postgresql:postgresql:${versions.postgresql}"

    testImplementation "org.springframework.boot:spring-boot-starter-test"
    testImplementation group: 'junit', name: 'junit', version: '4.12'

    integrationTestImplementation "org.springframework.boot:spring-boot-starter-test"
    integrationTestImplementation "org.springframework:spring-test"
    integrationTestImplementation 'io.rest-assured:rest-assured:3.3.0'
    integrationTestImplementation "com.fasterxml.jackson.core:jackson-databind:2.11.0"
    integrationTestImplementation 'junit:junit:4.12'
}

task integrationTest(type: Test) {
    description = 'Runs integration tests.'
    group = 'verification'

    testClassesDirs = sourceSets.integrationTest.output.classesDirs
    classpath = sourceSets.integrationTest.runtimeClasspath
}

2 Answers2

0

I believe what you're looking for is the SpringBootTest annotation. Add the following annotation atop your test class.

@RunWith(SpringRunner.class)
@SpringBootTest

Should you need, you can pass additional properties into the Spring environment by including them in your SpringBootTest annotation, as in

@SpringBootTest(properties = "com.mycompany.myclass.someproperty=some_value")

If the properties you're trying to load are in a profile specific property file, you can activate that profile with

@ActiveProfiles(value = "my_profile")
lane.maxwell
  • 5,002
  • 1
  • 20
  • 30
  • I used @RunWith(SpringRunner.class) @SpringBootTest for another project and that worked, but when used on this project, I get: `Failed to introspect Class [org.example.forex.service.CurrencyService]` and the same error message for other spring manage beans –  Oct 27 '20 at 19:34
  • This is a separate issue and sounds as if there are dependencies missing on the classpath but it's impossible to determine from just this comment. – lane.maxwell Oct 27 '20 at 22:37
  • I've added build.gradle file to the original post –  Oct 28 '20 at 10:32
0

Okay. Thanks to @lane.maxwell for the clue, I figured out the missing dependency.

These do work as @lane.maxwell says:

@RunWith(SpringRunner.class)
@SpringBootTest

Basically, my app uses a database and I need to to add the DB dependencies to build.gradle for the integration tests to work:

integrationTestImplementation'org.springframework.boot:spring-boot-starter-data-jpa'
integrationTestImplementation "org.postgresql:postgresql:${versions.postgresql}"