DataStore의 테스트 코드를 작성하다가 TemporaryFolder의 존재를 알게 됐다.
https://junit.org/junit4/javadoc/4.12/org/junit/rules/TemporaryFolder.html
https://www.geeksforgeeks.org/junit-temporaryfolder-rulepost/
TemporaryFolder의 역할
테스트 중에 임시 파일과 임시 디렉토리를 관리하는 JUnit의 Rule이다.
TemporaryFolder에 @Rule 어노테이션을 달면, Junit이 임시 파일과 폴더를 테스트 실행 전에 새로 생성하고 테스트 완료 후(성공이든 실패든 상관없이)에 삭제한다.
TemporaryFolder를 사용하면 좋은 점 (장점)
1. 테스트 별로 파일이 독립적이다
파일 이름이 같더라도 테스트 간 임시 작업 공간이 분리되는 셈이다. 테스트가 서로 영향을 주지 않는다.
2. 자동으로 리소스를 정리해준다.
테스트가 끝나면 자동으로 테스트용 임시 파일과 폴더가 모두 지워진다.
3. 가독성 및 유지보수성이 증가된다.
임시 파일을 관리하기 위한 보일러 코드를 작성할 필요가 없어서 가독성과 유지보수성이 증가한다.
TemporaryFolder 사용 예제
이번에 내가 작성한 코드
import androidx.datastore.core.DataStore
import androidx.datastore.preferences.core.PreferenceDataStoreFactory
import androidx.datastore.preferences.core.Preferences
import junit.framework.TestCase.assertEquals
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.Job
import kotlinx.coroutines.flow.first
import kotlinx.coroutines.test.TestDispatcher
import kotlinx.coroutines.test.TestScope
import kotlinx.coroutines.test.UnconfinedTestDispatcher
import kotlinx.coroutines.test.runTest
import org.junit.Before
import org.junit.Rule
import org.junit.Test
import org.junit.rules.TemporaryFolder
@OptIn(ExperimentalCoroutinesApi::class)
class PhotoLocationReferencesTest {
private lateinit var testDataStore: DataStore<Preferences>
private lateinit var photoLocationReferences: PhotoLocationReferences
private lateinit var testDispatcher: TestDispatcher
private lateinit var testScope: TestScope
@get:Rule
val temporaryFolder = TemporaryFolder.builder().assureDeletion().build()
@Before
fun setUp() {
println("setUp")
testDispatcher = UnconfinedTestDispatcher()
testScope = TestScope(testDispatcher + Job())
testDataStore =
PreferenceDataStoreFactory.create(
scope = testScope,
produceFile = { temporaryFolder.newFile("photo_location.preferences_pb") }
)
photoLocationReferences = PhotoLocationPreferencesImpl(testDataStore)
}
@Test
fun `저장된_시간_정보가_없을_경우_0L_반환`() = runTest {
println("Temporary File Path: ${temporaryFolder.root.absolutePath}")
val syncTime = photoLocationReferences.timeSyncDatabaseFlow.first()
assertEquals(syncTime, 0L)
}
@Test
fun `저장된_시간_정보를_반환`() = runTest {
println("Temporary File Path: ${temporaryFolder.root.absolutePath}")
val time = System.currentTimeMillis()
photoLocationReferences.updateTimeSyncDatabase(time)
val syncTime = photoLocationReferences.timeSyncDatabaseFlow.first()
assertEquals(time, syncTime)
}
}
1. temporarayFolder.builder()의 assureDeletion()은 TemporaryFolder가 임시 파일과 폴더의 삭제를 보장한다.
삭제 실패 시 AssertionError가 발생한다. 기본적으로 TemporaryFolder는 리소스 삭제 성공을 보장하지 못한다. 리소스 삭제 실패 시에 익셉션을 throw하는 것도 없다.
2. 테스트별 temporaryFolder.root.absolutePath의 값이 다르다.
'빈 구멍 채우기' 카테고리의 다른 글
[삽질기록] Kotlinx Serialization에 접근할 수 없음 (0) | 2025.01.17 |
---|---|
[Java][Kotlin] 자바의 직렬화 Serialization과 코틀린의 Kotlin Serialization (1) | 2025.01.16 |
[모바일] OWASP Mobile Application Security (1) | 2025.01.03 |
[삽질기록][Android] Git 리모트에서 받아온 소스를 안드로이드 스튜디오에서 안드로이드 프로젝트로 읽지 못한다. (1) | 2024.11.30 |
[Android] Secrets Gradle Plugin for Android (1) | 2024.11.28 |