์ค๋ํ
09/07/2023, 2:09 PMjw
09/07/2023, 2:14 PM์ค๋ํ
09/07/2023, 2:25 PMclass TestClock : Clock {
private var testInstant: Instant? = null
override fun now(): Instant {
return testInstant ?: Clock.System.now()
}
fun fixAt(time: LocalDateTime) {
testInstant = time.toInstant(TimeZone.UTC)
}
fun reset() {
testInstant = null
}
}
you mean using fake clock instance for test like this?jw
09/07/2023, 2:25 PMjw
09/07/2023, 2:30 PMMustafa Ozhan
09/08/2023, 8:02 AMfun nowAsInstant() = Clock.System.now()
fun nowAsLong() = nowAsInstant().toEpochMilliseconds()
ptsiogas
09/08/2023, 8:40 AMKlitos Kyriacou
09/08/2023, 8:49 AMClock
instance as a parameter to any method (or any class constructor) that needs the time. Pass it Clock.System
in production, and TestClock
in unit tests, where you define TestClock.now()
to return a test value. Something analogous to java.time.Clock.systemUTC()
vs java.time.Clock.fixed()
.CLOVIS
09/08/2023, 9:46 AMThat's really bad: it means you can't switch the clock to fake times. You're going to regret this a lot when you need to debug something that only happens on a very specific dateCopy codefun nowAsInstant() = Clock.System.now()
ptsiogas
09/08/2023, 9:54 AMmilliseconds: Long
as an input, even now date should be an input. With that way you wonโt have the need for Clock.Mustafa Ozhan
09/08/2023, 10:03 AMThatโs really bad: it means you canโt switch the clock to fake times.It will happen only if you use these directly in a class, but you can have interfaces to abstract away these implementations as a result you can always mock them. ie.
every { appStorage.premiumEndDate }
.returns(nowAsLong() + 1.seconds.inWholeMilliseconds)
CLOVIS
09/08/2023, 10:17 AMClock
?Javier
09/08/2023, 10:19 AMMustafa Ozhan
09/08/2023, 11:05 AM์ค๋ํ
09/10/2023, 1:14 AMJoffrey
09/11/2023, 12:16 AM์ค๋ํ
09/11/2023, 12:26 AMjw
09/11/2023, 12:27 AMjw
09/11/2023, 12:27 AM์ค๋ํ
09/11/2023, 12:41 AMjw
09/11/2023, 12:42 AM์ค๋ํ
09/11/2023, 12:45 AMCLOVIS
09/11/2023, 7:47 AMFakes should be shared, possibly even tested themselvesIf anyone's interested, here's a codebase that does that: https://gitlab.com/opensavvy/formulaide The domain layer (
:core
) contains data classes and service declarations as interfaces. The :fake
module contains in-memory implementations of all these interfaces. The :test
module contains test suites that check the validity of an implementation. All implementations of the interface (:fake
which is in-memory, :mongo
which handles persistence, :remote
for client-server communication, etc) are all tested using the same test suite. I'm experimenting with having UI tests also use the same suite.
No matter what technologies you use, the only real requirement for doing that is to be able to declare tests programmatically. In that project, I'm hacking around through JUnit5 test inheritance and Kotlin/JS's test runners internalsโฆ I'm working on releasing that test harness as a standalone library, but any other test framework with this feature (e.g. Kotest) would work as well.