-
Notifications
You must be signed in to change notification settings - Fork 0
[Test] HomeViewModel 테스트 코드 작성 #238
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
|
Important Review skippedAuto reviews are limited based on label configuration. 🏷️ Required labels (at least one) (1)
Please check the settings in the CodeRabbit UI or the You can disable this status message by setting the Walkthrough테스트 인프라 모듈을 추가하여 단위 테스트 기반을 구축합니다. 테스트 라이브러리 의존성을 도입하고, 테스트 유틸리티(MainDispatcherRule), 테스트 데이터 팩토리, 가짜 저장소 구현을 제공하며, HomeViewModel 테스트 스위트를 작성합니다. Changes
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes
Possibly related PRs
Suggested reviewers
Poem
Pre-merge checks and finishing touches❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
|
@coderabbitai review |
✅ Actions performedReview triggered.
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 9
📜 Review details
Configuration used: CodeRabbit UI
Review profile: ASSERTIVE
Plan: Pro
📒 Files selected for processing (16)
build-logic/src/main/java/com/yapp/KotlinAndroid.kt(1 hunks)build-logic/src/main/java/yapp.android.feature.gradle.kts(1 hunks)core/testing/.gitignore(1 hunks)core/testing/build.gradle.kts(1 hunks)core/testing/src/main/java/com/yapp/testing/MainDispatcherRule.kt(1 hunks)core/testing/src/main/java/com/yapp/testing/data/AttendanceTestData.kt(1 hunks)core/testing/src/main/java/com/yapp/testing/data/OperationsTestData.kt(1 hunks)core/testing/src/main/java/com/yapp/testing/data/ScheduleTestData.kt(1 hunks)core/testing/src/main/java/com/yapp/testing/repository/FakeAttendanceRepository.kt(1 hunks)core/testing/src/main/java/com/yapp/testing/repository/FakeOperationsRepository.kt(1 hunks)core/testing/src/main/java/com/yapp/testing/repository/FakeScheduleRepository.kt(1 hunks)feature/home/src/test/java/com/yapp/home/ExampleUnitTest.kt(0 hunks)feature/home/src/test/java/com/yapp/home/HomeViewModelTest.kt(1 hunks)feature/schedule/src/main/java/com/yapp/feature/schedule/ScheduleScreen.kt(6 hunks)gradle/libs.versions.toml(3 hunks)settings.gradle.kts(1 hunks)
💤 Files with no reviewable changes (1)
- feature/home/src/test/java/com/yapp/home/ExampleUnitTest.kt
🧰 Additional context used
📓 Path-based instructions (6)
**/*.gradle.kts
📄 CodeRabbit inference engine (AGENTS.md)
Use Gradle Kotlin DSL for build scripts (.gradle.kts)
Files:
settings.gradle.ktsbuild-logic/src/main/java/yapp.android.feature.gradle.ktscore/testing/build.gradle.kts
**/*.kt
📄 CodeRabbit inference engine (AGENTS.md)
**/*.kt: Use 4-space indentation in Kotlin source files
Avoid wildcard imports and keep imports sorted in Kotlin files
Naming — Classes/Objects use UpperCamelCase
Naming — Functions and variables use lowerCamelCase
Naming — Constants use UPPER_SNAKE_CASE
Naming — Packages are lowercase
Files:
core/testing/src/main/java/com/yapp/testing/data/OperationsTestData.ktcore/testing/src/main/java/com/yapp/testing/data/AttendanceTestData.ktfeature/schedule/src/main/java/com/yapp/feature/schedule/ScheduleScreen.ktcore/testing/src/main/java/com/yapp/testing/repository/FakeAttendanceRepository.ktcore/testing/src/main/java/com/yapp/testing/data/ScheduleTestData.ktcore/testing/src/main/java/com/yapp/testing/MainDispatcherRule.ktbuild-logic/src/main/java/com/yapp/KotlinAndroid.ktfeature/home/src/test/java/com/yapp/home/HomeViewModelTest.ktcore/testing/src/main/java/com/yapp/testing/repository/FakeOperationsRepository.ktcore/testing/src/main/java/com/yapp/testing/repository/FakeScheduleRepository.kt
**/src/main/java/**/*.kt
📄 CodeRabbit inference engine (AGENTS.md)
Place Kotlin production source under module/src/main/java
Files:
core/testing/src/main/java/com/yapp/testing/data/OperationsTestData.ktcore/testing/src/main/java/com/yapp/testing/data/AttendanceTestData.ktfeature/schedule/src/main/java/com/yapp/feature/schedule/ScheduleScreen.ktcore/testing/src/main/java/com/yapp/testing/repository/FakeAttendanceRepository.ktcore/testing/src/main/java/com/yapp/testing/data/ScheduleTestData.ktcore/testing/src/main/java/com/yapp/testing/MainDispatcherRule.ktbuild-logic/src/main/java/com/yapp/KotlinAndroid.ktcore/testing/src/main/java/com/yapp/testing/repository/FakeOperationsRepository.ktcore/testing/src/main/java/com/yapp/testing/repository/FakeScheduleRepository.kt
{core/ui,core/designsystem,feature/*}/src/main/java/**/*.kt
📄 CodeRabbit inference engine (AGENTS.md)
{core/ui,core/designsystem,feature/*}/src/main/java/**/*.kt: Compose/UI: limit to one public component per file
Compose/UI: filename must match the public class/composable it contains
Files:
feature/schedule/src/main/java/com/yapp/feature/schedule/ScheduleScreen.kt
**/src/{test,androidTest}/**/*Test.kt
📄 CodeRabbit inference engine (AGENTS.md)
Name test classes/files with the suffix "Test"
Files:
feature/home/src/test/java/com/yapp/home/HomeViewModelTest.kt
**/src/test/**/*.kt
📄 CodeRabbit inference engine (AGENTS.md)
Place unit tests under module/src/test
Files:
feature/home/src/test/java/com/yapp/home/HomeViewModelTest.kt
🧠 Learnings (9)
📚 Learning: 2025-01-09T07:44:48.036Z
Learnt from: ashwon12
Repo: YAPP-admin/yappu-world-android PR: 5
File: feature/signup/build.gradle.kts:1-47
Timestamp: 2025-01-09T07:44:48.036Z
Learning: Pure Kotlin modules (model, data-api) should only have Kotlin dependencies and no Android-specific dependencies.
Applied to files:
gradle/libs.versions.tomlbuild-logic/src/main/java/com/yapp/KotlinAndroid.ktcore/testing/build.gradle.kts
📚 Learning: 2025-01-08T06:56:07.931Z
Learnt from: jinukeu
Repo: YAPP-admin/yappu-world-android PR: 5
File: core/domain/build.gradle.kts:1-4
Timestamp: 2025-01-08T06:56:07.931Z
Learning: In this project's architecture, the domain module is designed as an Android library module, not a pure Kotlin library, following Google's recommended architecture guidelines.
Applied to files:
gradle/libs.versions.tomlbuild-logic/src/main/java/yapp.android.feature.gradle.ktscore/testing/build.gradle.kts
📚 Learning: 2025-09-19T11:37:27.391Z
Learnt from: CR
Repo: YAPP-admin/yappu-world-android PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-09-19T11:37:27.391Z
Learning: Applies to **/src/androidTest/**/*.kt : Place instrumented tests under module/src/androidTest
Applied to files:
gradle/libs.versions.tomlsettings.gradle.ktscore/testing/src/main/java/com/yapp/testing/data/OperationsTestData.ktbuild-logic/src/main/java/yapp.android.feature.gradle.ktsbuild-logic/src/main/java/com/yapp/KotlinAndroid.ktfeature/home/src/test/java/com/yapp/home/HomeViewModelTest.ktcore/testing/build.gradle.kts
📚 Learning: 2025-09-19T11:37:27.391Z
Learnt from: CR
Repo: YAPP-admin/yappu-world-android PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-09-19T11:37:27.391Z
Learning: Applies to **/src/test/**/*.kt : Place unit tests under module/src/test
Applied to files:
gradle/libs.versions.tomlsettings.gradle.ktsbuild-logic/src/main/java/com/yapp/KotlinAndroid.ktfeature/home/src/test/java/com/yapp/home/HomeViewModelTest.ktcore/testing/build.gradle.kts
📚 Learning: 2025-09-19T11:37:27.391Z
Learnt from: CR
Repo: YAPP-admin/yappu-world-android PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-09-19T11:37:27.391Z
Learning: Applies to **/src/{test,androidTest}/**/*Test.kt : Name test classes/files with the suffix "Test"
Applied to files:
gradle/libs.versions.tomlcore/testing/src/main/java/com/yapp/testing/data/OperationsTestData.ktcore/testing/src/main/java/com/yapp/testing/data/ScheduleTestData.ktbuild-logic/src/main/java/com/yapp/KotlinAndroid.ktfeature/home/src/test/java/com/yapp/home/HomeViewModelTest.ktcore/testing/build.gradle.kts
📚 Learning: 2025-01-08T06:56:08.678Z
Learnt from: jinukeu
Repo: YAPP-admin/yappu-world-android PR: 5
File: settings.gradle.kts:38-42
Timestamp: 2025-01-08T06:56:08.678Z
Learning: In Gradle settings files, module declarations should be unique to prevent build issues. Each module should only be included once in the `include` statements.
Applied to files:
settings.gradle.kts
📚 Learning: 2025-09-19T11:37:27.391Z
Learnt from: CR
Repo: YAPP-admin/yappu-world-android PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-09-19T11:37:27.391Z
Learning: Applies to **/src/main/java/**/*.kt : Place Kotlin production source under module/src/main/java
Applied to files:
build-logic/src/main/java/com/yapp/KotlinAndroid.ktcore/testing/build.gradle.kts
📚 Learning: 2025-09-19T11:37:27.391Z
Learnt from: CR
Repo: YAPP-admin/yappu-world-android PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-09-19T11:37:27.391Z
Learning: Applies to **/*.kt : Avoid wildcard imports and keep imports sorted in Kotlin files
Applied to files:
build-logic/src/main/java/com/yapp/KotlinAndroid.kt
📚 Learning: 2025-09-19T11:37:27.391Z
Learnt from: CR
Repo: YAPP-admin/yappu-world-android PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-09-19T11:37:27.391Z
Learning: Applies to **/*.gradle.kts : Use Gradle Kotlin DSL for build scripts (.gradle.kts)
Applied to files:
build-logic/src/main/java/com/yapp/KotlinAndroid.ktcore/testing/build.gradle.kts
🧬 Code graph analysis (1)
core/testing/src/main/java/com/yapp/testing/data/ScheduleTestData.kt (1)
feature/schedule/src/main/java/com/yapp/feature/schedule/component/DateGroupedScheduleItem.kt (1)
ScheduleList(140-197)
🔇 Additional comments (20)
core/testing/.gitignore (1)
1-1: LGTM!새로운
core/testing모듈의 빌드 출력을 올바르게 무시하는 표준.gitignore항목입니다.gradle/libs.versions.toml (1)
80-81: 테스트 라이브러리 추가가 적절합니다.
mockk와kotlinx-coroutines-test라이브러리가 올바르게 선언되었습니다. 기존 파일의 패턴을 따르고 있으며, 테스트 인프라 구축에 필요한 핵심 의존성입니다.core/testing/src/main/java/com/yapp/testing/data/ScheduleTestData.kt (1)
22-155: 잘 구성된 테스트 데이터 팩토리입니다.PR 목적에 맞게 변수 대신 함수로 구현하여
copy()를 통한 유연한 조정이 가능합니다. 다양한 상태(PENDING, DONE, ONGOING)와 타입(SESSION, TASK)을 커버하는 포괄적인 테스트 데이터를 제공하며,notices()헬퍼 함수가 적절히 private으로 캡슐화되어 있습니다.feature/schedule/src/main/java/com/yapp/feature/schedule/ScheduleScreen.kt (2)
163-197: 양방향 동기화 로직이 올바르게 구현되었습니다.선택된 탭과 페이저 간의 양방향 동기화가
rememberUpdatedState와LaunchedEffect를 적절히 활용하여 구현되었습니다.distinctUntilChanged()를 사용해 중복 이벤트를 방지하는 점도 좋습니다.
199-211: 구현이 올바릅니다만, PR 범위와의 관련성을 확인해주세요.
SchedulePagerState클래스는@Stable어노테이션과 함께 적절하게 구현되었으며, 불필요한 애니메이션을 방지하는 최적화(Line 206)도 포함되어 있습니다. 다만 이 변경사항은 HomeViewModel 테스트 작성이라는 PR의 주요 목표와 직접적인 관련이 없어 보입니다.이 변경사항이 PR 설명에 언급된 "previously omitted commit (a1805c2)"에 해당하는지 확인해주세요.
core/testing/src/main/java/com/yapp/testing/data/OperationsTestData.kt (1)
3-5: 테스트 데이터 구조가 적절합니다.간단하고 명확한 테스트 데이터 팩토리입니다. PR 설명에서 언급한 대로 함수 형태로 제공되어
copy()를 통한 유연한 조정이 가능합니다.core/testing/src/main/java/com/yapp/testing/data/AttendanceTestData.kt (1)
10-41: 테스트 데이터가 잘 구조화되어 있습니다.출석 통계와 이력 데이터가 다양한 시나리오(정상 출석, 지각, 결석)를 대표하도록 적절하게 구성되어 있습니다.
@file:Suppress("MagicNumber")어노테이션도 테스트 데이터의 특성상 적절합니다.feature/home/src/test/java/com/yapp/home/HomeViewModelTest.kt (7)
24-46: 테스트 셋업이 올바르게 구성되었습니다.
MainDispatcherRule을 사용한 코루틴 테스트 환경 설정과 Fake Repository를 통한 의존성 주입이 적절하게 구현되었습니다.
48-77: 초기 상태 및 진입 테스트가 잘 작성되었습니다.로딩 상태 확인, 첫 진입시 API 호출, 그리고 재진입시 중복 호출 방지에 대한 테스트가 명확하게 구현되어 있습니다. 특히 캐싱 동작을 검증하는 idempotency 테스트가 좋습니다.
79-115: 새로고침 및 캐싱 로직 테스트가 적절합니다.명시적 새로고침시 항상 API를 호출하는 동작과, 기본 규칙 링크의 캐싱 동작이 잘 검증되고 있습니다.
async를 사용한 side effect 검증 패턴도 올바릅니다.
117-143: 출석 코드 다이얼로그 테스트가 잘 구현되었습니다.다이얼로그의 상태 초기화와 입력값에 따른 버튼 활성화 로직이 명확하게 검증되고 있습니다.
145-168: 출석 요청 성공 시나리오가 포괄적으로 테스트되었습니다.출석 코드 제출 후 다이얼로그 닫힘, 출석 상태 갱신, 체크인 가능 여부 업데이트, 그리고 실제 출석 데이터 기록까지 전체 플로우가 잘 검증되고 있습니다.
170-185: 에러 처리 테스트가 올바르게 작성되었습니다.출석 코드가 틀렸을 때 에러 상태가 올바르게 표시되는지 검증하고 있습니다.
CodeNotCorrectException을 사용한 실패 시나리오 테스트가 적절합니다.
24-186: HomeViewModel 테스트 스위트가 매우 잘 작성되었습니다.PR의 핵심인 HomeViewModel 테스트가 다음과 같은 측면에서 훌륭하게 구현되었습니다:
- 초기 상태, 진입, 새로고침, 캐싱, 에러 처리 등 주요 시나리오 커버
- Fake Repository를 활용한 격리된 단위 테스트
- 멱등성(idempotency) 검증
- 명확한 테스트 메서드 이름 (한글 사용이 프로젝트 컨텍스트에 적합함)
- AAA(Arrange-Act-Assert) 패턴 준수
첫 ViewModel 테스트 작성치고는 매우 완성도가 높습니다!
core/testing/src/main/java/com/yapp/testing/repository/FakeAttendanceRepository.kt (1)
9-29: Fake Repository가 잘 설계되었습니다.PR 설명에서 언급한 대로 stub/mock 대신 Fake 구현을 선택한 것이 적절합니다. 다음과 같은 장점이 있습니다:
var속성으로 테스트별 데이터 커스터마이징 가능postedAttendances리스트로 호출 검증 가능postAttendanceResult로 성공/실패 시나리오 제어 가능- 인메모리 동작을 잘 모사하여 실제 Repository의 동작과 유사
core/testing/src/main/java/com/yapp/testing/repository/FakeOperationsRepository.kt (2)
20-21: 테스트 검증을 위한 카운터가 잘 구현되었습니다.
basicRuleRequestCount를 사용하여getBasicRuleLink()호출 횟수를 추적하는 것은 테스트 검증에 유용합니다.private set을 사용하여 외부에서 읽기만 가능하도록 제한한 점도 좋습니다.
40-42: Flow emission을 위한 헬퍼 메서드가 적절합니다.
emitPositionConfigs()메서드를 통해 테스트에서positionConfigsFlow의 새로운 값을 emit할 수 있도록 한 점이 좋습니다. MutableStateFlow를 직접 노출하지 않고 메서드로 감싸서 캡슐화를 유지한 것도 적절합니다.core/testing/src/main/java/com/yapp/testing/repository/FakeScheduleRepository.kt (3)
20-25: 기본값 폴백 로직이 잘 구현되었습니다.
sessionDetailMap이 비어있을 경우 기본 세션 상세 정보를 추가하는 로직이 적절합니다. 이를 통해getSessionDetail()메서드에서 안전한 폴백이 가능합니다.
28-36: 테스트 검증을 위한 추적 상태가 잘 구현되었습니다.카운터(
refreshUpcomingSessionsCount)와 마지막 요청 파라미터 추적(lastSessionsRange,lastScheduleYearMonth,lastRequestedSessionId)을 통해 테스트에서 리포지토리 메서드 호출을 검증할 수 있습니다.private set을 사용하여 외부에서는 읽기만 가능하도록 제한한 점도 좋습니다.
67-79: 헬퍼 메서드와 캐싱 로직이 적절합니다.
setMonthlySchedule()과setSessionDetail()을 통해 테스트에서 동적으로 데이터를 설정할 수 있고,fetchMonthlySchedule()의 per-year/month 캐싱 로직도 잘 구현되었습니다. 이를 통해 테스트에서 다양한 시나리오를 쉽게 검증할 수 있습니다.
core/testing/src/main/java/com/yapp/testing/MainDispatcherRule.kt
Outdated
Show resolved
Hide resolved
core/testing/src/main/java/com/yapp/testing/repository/FakeOperationsRepository.kt
Show resolved
Hide resolved
core/testing/src/main/java/com/yapp/testing/repository/FakeScheduleRepository.kt
Show resolved
Hide resolved
core/testing/src/main/java/com/yapp/testing/repository/FakeScheduleRepository.kt
Show resolved
Hide resolved
| @Test | ||
| fun 홈_화면에_입장하면_다가오는_세션을_가져오고_로딩을_종료한다() = runTest { | ||
| // when | ||
| viewModel.store.onIntent(HomeIntent.EnterHomeScreen) | ||
|
|
||
| // then | ||
| assertEquals(1, fakeScheduleRepository.refreshUpcomingSessionsCount) | ||
| val state = viewModel.store.uiState.value | ||
| assertFalse(state.isLoading) | ||
| assertEquals(fakeScheduleRepository.upcomingSessionInfo, state.upcomingSession) | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
행위 기반을 위주로 테스트 코드를 작성하셨군요.
행위 기반 테스트의 경우 내성이 약하다는 단점이 있어서 상태 기반 테스트로 작성하는건 어떨까요?
예를 들어서, '강아지가 온다'를 각각 테스트로 작성한다 하면 ...
상태 기반 테스트
class Dog(var position: Int = 0) {
fun come() {
position += 10
}
}
@Test
fun `come should move dog to position 10`() {
val dog = Dog()
dog.come()
// 상태 검증: 강아지가 어디에 있는가?
assertEquals(10, dog.position)
}행위 기반 테스트
interface Leg {
fun move()
}
class Dog(private val leg: Leg) {
fun come() {
leg.move()
leg.move()
leg.move()
leg.move()
}
}
@Test
fun `come should move legs 4 times`() {
val leg = mockk<Leg>()
every { leg.move() } just Runs
val dog = Dog(leg)
dog.come()
// 행위 검증: 다리를 4번 움직였는가?
verify(exactly = 4) { leg.move() }
}행위 기반 테스트의 경우 '다리를 4번 움직였는가'를 검증하는데 이건 구현 세부사항이 결합되어 있어요. 만약 구현 세부사항이 강아지가 뛰어서 2번만에 온다는 걸로 바뀌게 된다면 테스트가 실패하게됩니다. (실제로 강아지가 움직인 위치는 동일함에도 테스트가 실패하기 때문에 테스트 신뢰도가 낮아지게 돼요)
반면에 상태 기반은 강아지가 원하는 위치에 왔는가만 검증하니, 리팩토링에 훨씬 유연합니다.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
행위 기반을 사용하는 경우는 에러가 발생한 경우 Crashlytics 로그를 전송한다. 가 떠오르네요
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
assertEquals(1, fakeScheduleRepository.refreshUpcomingSessionsCount)
이 부분에 대한 검증은 행위 검증이라서 빼면 어떨까 싶습니다.
다른 코드에서도 행위 검증 관련 코드는 빼면 어떨까요?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@jinukeu
ViewModel 테스트의 경우 사용자가 행동(Intent)를 했을 때 State가 제대로 바뀌었는지 검증하기 위한 것이라고 생각하는데요
캐싱 로직이나 초기화된 상태에서 화면 재진입 시 API가 다시 호출되지 않는지 테스트하기 위해 API 호출 횟수 또한 검증했는데 이를 상태 기반만으로 검증을 한다면
@Test
fun 홈_화면에_입장하면_다가오는_세션을_가져오고_로딩을_종료한다() = runTest {
// given
fakeScheduleRepository.upcomingSessionInfo = ScheduleTestData.upcomingSessionInfo().copy(
sessionId = "12345"
)
// when
viewModel.store.onIntent(HomeIntent.EnterHomeScreen)
// then
val state = viewModel.store.uiState.value
assertFalse(state.isLoading)
assertEquals(fakeScheduleRepository.upcomingSessionInfo, state.upcomingSession)
}@Test
fun 홈_화면에_재진입해도_처음_한번만_다가오는_세션을_조회한다() = runTest {
// given
fakeScheduleRepository.upcomingSessionInfo = ScheduleTestData.upcomingSessionInfo().copy(
sessionId = "12345"
)
// when
viewModel.store.onIntent(HomeIntent.EnterHomeScreen)
fakeScheduleRepository.upcomingSessionInfo = ScheduleTestData.upcomingSessionInfo().copy(
sessionId = "2345"
)
viewModel.store.onIntent(HomeIntent.EnterHomeScreen)
// then
val state = viewModel.store.uiState.value
assertEquals(state.upcomingSessionInfo.sessionId, "12345")
}@Test
fun 기본_규칙_링크를_최초로_불러오면_캐싱된다() = runTest {
// given
fakeOperationRepository.basicRuleLink = "https://www.yapp.co.kr"
// when
viewModel.store.onIntent(HomeIntent.ClickBasicRuleLink)
// then
val state = viewModel.store.uiState.value
assertEquals(fakeOperationRepository.cachedBasicRuleLink, state.basicRuleLink)
}이런 식을 말씀하시는 걸까요??
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
캐싱이 올바르게 되는지는 Repository 구현체 테스트에 더 알맞은 것 같아서
아예, ViewModel 쪽에서 검증을 안하는 방법도 있을 것 같긴 합니다.
호출 횟수와 같은 행위에 가까운 로직보다 ViewModel의 State가 올바르게 변경되는지만 ViewModel 테스트에서 판단하면요
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
넵 댓글에 써주신 코드 스니펫이 제가 생각한 방법이에요
캐싱 관련 로직은 Repository 테스트 단에서 하는게 더 맞을거같아요!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
넵! 캐싱로직은 Repository 테스트에서 작성하는 걸로 할게요.
property 방식 써도 copy()는 사용 가능하서 테스트 데이터 변수로 바꿨습니다
jinukeu
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
테스트 코드를 행위 기반으로 작성할지, 상태 기반으로 작성할지 한번 논의해보면 좋을거같아요
|
혹시 AGP 버전도 내려주실 수 있을까요 .. ㅎ |
jinukeu
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM 입니다!
💡 Issue
🌱 Key changes
UnconfinedTestDispatcher 사용을 위한 DispatcherRule, 테스트 관련 Fake 객체를 격리시키기 위해 core:testing 모듈을 생성했습니다.
당장에는 FakeRepository만 있는 상황이라 data-api에 Fake 객체를 두어도 무방했지만, 추후 다른 모듈에 대한 Fake 객체도 필요할 가능성을 대비해서 모듈을 분리했습니다.
테스트 데이터의 경우 함수로 제공하였는데요.
변수에 저장해서 사용하는 방식에 비해 매번 호출되어 생성하는 비용이 발생하지만
copy() 메소드를 통해 테스트 데이터를 유연하게 조정할 수 있기 때문에 함수로 해뒀습니다.
또한 Repository의 경우 Stub이나 Mock이 아닌 Fake로 선언했는데요
Repository 내에서 인메모리 캐싱과 같은 로직이 있기도 해서 실제 동작을 흉내낸 Fake가 더 적합하다고 생각했습니다.
✅ To Reviewers
a1805c2 저번 PR에서 누락된 커밋도 같이 올렸어요
새로고침, API 캐싱 로직, 출석코드 입력쪽에 대한 검증을 주로 했는데요
추가하거나 없애도 될 부분 있으면 말씀해주세요!
저도 ViewModel 쪽 테스트 코드 작성은 처음이라서 피드백 환영해요!
📸 스크린샷
Summary by CodeRabbit
테스트
업데이트
기타
✏️ Tip: You can customize this high-level summary in your review settings.