0

For example, I have this Kotlin class and method (Spring-managed class if it matters):

import org.springframework.stereotype.Service
import java.time.LocalDateTime

data class TestObj(
    val msg: String,
    val dateTime: LocalDateTime
)

@Service
class TestAnotherService {
    fun doSmthng1(testObj: TestObj) {
        println("Oh my brand new object : $testObj")
    }
}

@Service
class TestService(
    private val testAnotherService: TestAnotherService
) {
    fun doSmthng() {
        testAnotherService.doSmthng1(TestObj("my message!", LocalDateTime.now()))
    }
}

How can I test that TestService passes TestObj with dateTime as LocalDateTime#now?

I have several solutions:

  1. Let's add a small delta in the comparison in the assertEquals.
  2. Let's verify that in the object that we passing in the TestAnotherService#doSmthng1 dateTime field is not null or even use Mockito#any.
  3. Let's mock call LocalDateTime#now using PowerMock or similar.
  4. Let's use DI. Create configuration with this bean:
@Configuration
class AppConfig {

    @Bean
    fun currentDateTime(): () -> LocalDateTime {
        return LocalDateTime::now
    }
}

And modify service that using LocalDateTime#now to this:

    fun doSmthng() {
        testAnotherService.doSmthng1(TestObj("my message!", currentDateTimeFunc.invoke()))
    }
  1. Just don't. This doesn't worth it to test LocalDateTime.

Which is an optimal solution? Or maybe there are other solutions?

  • I suggest that you study [Writing and testing convenience methods using Java 8 Date/Time classes](https://stackoverflow.com/questions/52956373/writing-and-testing-convenience-methods-using-java-8-date-time-classes) and [How to change the value new Date() in java](https://stackoverflow.com/questions/61470651/how-to-change-the-value-new-date-in-java). It’s in Java, but I certainly expect it will work in Kotlin too. – Ole V.V. Jun 08 '20 at 17:25
  • @OleV.V. I see. In those questions, people suggest using DI, or other ways to inject `Clock`. Thanks! – Alexey Vinogradov Jun 09 '20 at 10:46

1 Answers1

1

You can simply pass the current date as function parameter.

fun doSmthng(now: LocalDateTime = LocalDateTime.now()) {
    testAnotherService.doSmthng1(TestObj("my message!", now))
}

And in the test you can pass some specific date and assert on it. Idea is to inject the dependencies instead of creating explicitly in the function body.

sidgate
  • 14,650
  • 11
  • 68
  • 119