:kodee-greetings: Hey, I have a very simple quest...
# test
e
kodee greetings Hey, I have a very simple question that's been driving me a little potty when using Kotlin Test because I have seen some conflicting opinions
```class FakeRepo: Repo {
private val users = mutableSetOf<String>()
fun addUser(name: String) {
users.add(name)
}
fun getUserCount(): Int {
return users.size
}
}
class SomeService(val repo: Repo) {
fun addUser(name: String) {
userRepository.addUser(name)
}
fun getUserCount(): Int {
return userRepository.getUserCount()
}
}```
If you write tests in this form:
```class SomeServiceTest {
private val repo = FakeRepo()
private val sut = SomeService(repo)
@Test
fun test1() {
service.registerUser("Alice")
val result = sut.getUserCount()
assertEquals(1, result)
}
@Test
fun test2() {
service.registerUser("Bob")
service.registerUser("Charlie")
val result = sut.getUserCount()
assertEquals(2, result)
}
}```
Each individual test will pass if it executes first, but wont pass if it's executed after the other. As the order tests are run isn't guaranteed, this is a common cause of issues with fakes that hold state.
Am I right here? The correct approach would be to init
sut
in a
@BeforeTest
method right? One of my colleagues mentioned
FakeRepo
would be recreated every time without
@BeforeTest
d
Did you ever see https://opensavvy.gitlab.io/groundwork/prepared/docs/features/index.html? It should solve quite a few of these problems, and it supports running under Kotlin test https://opensavvy.gitlab.io/groundwork/prepared/docs/tutorials/index.html#__tabbed_1_1
❤️ 1
The idea is that prepared values are assured to be reinitialized explicitly on every test. No BeforeXXXs to reset them needed, plus there's quite a few nice features as a plus...
By the way, you could check out your question yourself by putting logs in FakeRepo (or println) and seeing if it's printed for each test or not.
e
Thanks, but not really looking to introduce a new test framework to solve it. The project is already too well established to shoehorn that in right now. Back to my og question, I am not sure I am right - it looks like
repo
and
sut
are generated every time so I guess this is likely only a problem when Singleton
object
are used. That seems to go against everything I thought I knew about kotlin tests
Perhaps this is just a best practise when mocking and not when using fakes because of the way mocking frameworks work 🤔
d
For sure `object`s are only loaded once... same with top-level `val`s.... As for Kotlin Test's behaviour it probably depends on the underlying test runner (junit, junit5...) since all it's annotations are just typealiases to the underlying framework... see: https://github.com/JetBrains/kotlin/blob/2.1.20/libraries/kotlin.test/junit/src/main/kotlin/Annotations.kt
I think junit has a properties file it uses for global configs...