日付を扱った単体テストを実施することがあったので、その際にモック化したり色々問題があったので、まとめてみました。
Hiltでの単体テストに関しては、こちらの記事を参考してください。
Mockkを導入
testImplementation("io.mockk:mockk:1.13.9")
日付ライブラリーの導入
日付関連のライブラリーとして、Androidに最適化されたthreetenbpを使用します。
ただし、単体テストをする際に注意点があります。
単体テストでは、threetenabpが使えないため、除外してthreetenbpを使用する必要があります。
implementation("com.jakewharton.threetenabp:threetenabp:1.4.6")
testImplementation("org.threeten:threetenbp:1.6.8") {
exclude("com.jakewharton.threetenabp:threetenabp:1.4.6")
}
日付の単体テスト
setUp()内で実施しているmockkStaticで、LocalDateTimeをモック化して、テスト対象のメソッド内で実装されているLocalDateTime.now()をlocalDateTimeの固定値を返すようにします。
@HiltAndroidTest
@Config(application = HiltTestApplication::class)
@RunWith(AndroidJUnit4::class)
class DateTimeTest {
@get:Rule
var hiltRule = HiltAndroidRule(this)
@Inject
lateinit var dateTimeRepository: DateTimeRepository
private val localDateTime = LocalDateTime.of(2023, 1, 1, 0, 0, 0)
@Before
fun setUp() {
hiltRule.inject()
mockkStatic(LocalDateTime::class)
every { LocalDateTime.now() } returns localDateTime
}
@After
fun close() {
clearAllMocks()
}
@Test
fun `日付テスト`() {
val dateTime = LocalDateTime.of(2023, 1, 1, 0, 0, 0)
val result = dateTimeRepository.getNow()
assertEquals(dateTime, result)
}
}
class DateTimeRepository @Inject constructor() {
fun getNow(): LocalDateTime {
return LocalDateTime.now()
}
}
まとめ
日付関連のメソッドで、now()を使用する場合に固定された値ではないと単体テスト出来ないと思いますのでモック化して単体テストを実施してください。
また、日付に関しては必要とした日付を理解出来ているのが、実装者だけだったりすることが多いので、是非単体テストを導入してください。