1

I have an extension class that implements BeforeAllCallback to set a random port like this.

import org.junit.jupiter.api.extension.ExtensionContext
import java.net.ServerSocket

class CustomExtension : org.junit.jupiter.api.extension.BeforeAllCallback {
    var port: Int? = null

    override fun beforeAll(context: ExtensionContext?) {
        port = getRandomPort()
    }
    
    private fun getRandomPort(): Int {
        ServerSocket(0).use { 
            serverSocket -> return serverSocket.localPort 
        }
    }

}

Also, I have a property defined in src/test/resources/application.yml like this.

app:
  random-port: 8765

This property is used by this configuration class.

import org.springframework.boot.context.properties.ConfigurationProperties
import org.springframework.boot.context.properties.ConstructorBinding

@ConstructorBinding
@ConfigurationProperties(prefix = "app")
data class PortProperty(
    val randomPort: Int
)

Question

How can I override that hard corded app.random-port when running my tests from the CustomExtension class? The idea is so that my PortProperty gets the right value and not the hard coded one.

My test framework is JUnit5.

import org.junit.jupiter.api.extension.ExtendWith
import org.springframework.boot.test.context.SpringBootTest

@SpringBootTest
@ExtendWith(CustomExtension::class)
class RandomPortTest {
}

Edit

The use case is actually to start a local dynamo db using the AWS DynamoDBLocal library for the test classes.

billydh
  • 975
  • 11
  • 27
  • I don't think you want an extension if you only need to override the port. Look at `DynamicPropertySource` or `ApplicationContextInitializer`. Ex: https://stackoverflow.com/questions/31058489/override-default-spring-boot-application-properties-settings-in-junit-test-with https://docs.spring.io/spring-framework/docs/current/spring-framework-reference/testing.html#testcontext-ctx-management – Laksitha Ranasingha Oct 14 '20 at 23:17
  • The use case is actually to start a local dynamo db using the AWS DynamoDBLocal library, that is why I want it to be an extension so I can do the same for each test class. – billydh Oct 14 '20 at 23:29

1 Answers1

1

You can set the app.random-port system property in the beforeAll method. As system properties have higher priority than properties files, the port value from the application.yml will get overridden:

override fun beforeAll(context: ExtensionContext?) {
    port = getRandomPort()
    System.setProperty("app.random-port", port?.toString())
}
Mafor
  • 9,668
  • 2
  • 21
  • 36