Reputation: 1150
I have an integration test where I start an embedded MongoDB as a companion object. I want to reuse this piece of code and I am not sure if inheritance is the way to go (if possible).
It is a Spring Boot application:
This is my test:
@RunWith(SpringRunner::class)
@SpringBootTest
class RequestRepositoryTest {
@Autowired lateinit var requestRepository: RequestRepository
companion object {
private val starter = MongodStarter.getDefaultInstance()
private var _mongod: MongodProcess? = null
private var _mongo: MongoClient? = null
@BeforeClass
@JvmStatic fun beforeTest(){
val port = 27017
val _mongodExe = starter.prepare(MongodConfigBuilder()
.version(Version.Main.DEVELOPMENT)
.net(Net("localhost", port, Network.localhostIsIPv6()))
.build())
_mongod = _mongodExe.start()
_mongo = MongoClient("localhost", port)
}
@AfterClass
@JvmStatic fun afterTest(){
_mongod?.stop()
}
}
@Test
fun store() {
val id = requestRepository.store(Request(requestId = "123"))
assertNotNull(id)
}
}
My repository class:
@Repository
class RequestRepository @Autowired constructor(val datastore: Datastore)
{
fun store(request : Request) : String =
datastore.save(request).id.toString()
}
So my question is which is the 'correct' way to go about this in Kotlin.
Update edit: As an external object the test now looks a lot cleaner and the JUnit external resource is completely reusable across test classes:
Thanks @Lovis
@RunWith(SpringRunner::class)
@SpringBootTest
class RequestRepositoryTest {
companion object {
@ClassRule
@JvmField
val mongoServer = MongoServer
}
@Autowired lateinit var requestRepository: RequestRepository
@Test
fun store() {
val id = requestRepository.store(Request(requestId = "123"))
assertNotNull( id )
assertTrue { ObjectId.isValid(id) }
}
}
Upvotes: 1
Views: 1195
Reputation: 10057
You should be able to achieve what you want using jUnit's @ClassRule
and ExternalResource
. No Kotlin magic needed :-)
Define an object
in a separate File:
object MongoServer : ExternalResource() {
@Throws(Throwable::class)
override fun before() {
// before class
}
override fun after() {
// after class
}
}
Then use it within each test:
companion object {
@ClassRule
@JvmField
val mongoServer = MongoServer
}
The ClassRule
annotation does the trick here, the companion object
is necessary to make it static and the @JvmField
annotation is necessary to make the field public. Those are restrictions by jUnit's rule system.
Upvotes: 2