Skip to content
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

BookmarkViewModelTest #39

Open
wants to merge 3 commits into
base: dev
Choose a base branch
from
Open

BookmarkViewModelTest #39

wants to merge 3 commits into from

Conversation

Guri999
Copy link
Collaborator

@Guri999 Guri999 commented Jan 13, 2025

📝작업 내용

북마크 화면 뷰모델 테스트

@Guri999 Guri999 self-assigned this Jan 13, 2025
import kr.co.model.FileInfo.Type.PDF
import java.time.LocalDateTime

val PDF_DUMMY = FileInfo(
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

테스트용 데이터를 공유해야하는 이유가 궁금합니다.
A 피처 모듈, B 피처 모듈에서 이것으로 동일하게 테스트를 한다면, 만약 누군가 테스트 데이터를 변경하면 다른 모듈의 테스트 코드가 실패할 수 있을 것 같습니다.
변경된 파일만 테스트를 한다면 이러한 테스트 코드 실패를 늦게 발견하게 될 것 같습니다.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

수정하겠습니다

import kr.co.data.repository.BookmarkRepository
import kr.co.model.FileInfo

class TestBookmarkRepository: BookmarkRepository {
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

이런 특정 도메인/피처와 연관되는 테스트 클래스를 해당 모듈 내에 위치하는 것이 좋을 것 같습니다.
이 구조라면 테스트 모듈이 너무 비대해지고, 모든 피처 모듈을 다 알고 있어야 하기 때문에 테스트 빌드시 시간이 오래걸릴 것 같습니다.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

data모듈에 repsitory interface가 분리되어 data모듈만 바라봐서 모든 피처 모듈은 몰라도 괜찮지 않나요?

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(정정 : feature 모듈 -> data 모듈)
repsitory interface를 참조하기 위해 모든 data 모듈을 알고 있는것도 마찬가지로 많은 모듈을 참조하게 됩니다.
testing에서 data 모듈을 알고 있을 필요가 없는것도 같은 맥락에서 동일합니다.


viewModel.sideEffect.test {
awaitItem().also {
assert(it is BookmarkSideEffect.NavigateToPdf)
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

아래와 같이 작성하면 스마트 캐스팅을 활용할 수 있습니다.

val effect = awaitItem()
assert(effect is BookmarkSideEffect.NavigateToPdf)
assert(effect.path == file.path)

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

require를 활용한 방법은 어떤가요

require(this is BookmarkSideEffect.NavigateToPdf)
assert(path == file.path)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

테스트 코드에서 require는 적합하지 않습니다.
require의 용도는 입력값에 대한 사전 조건 확인을 의미합니다. 반면 assert는 실행 결과가 기대한 바와 맞는지에 대한 검증입니다.
테스트 코드는 동작한 코드의 결과물에 대한 "검증" 이 목적이므로 assert가 사용사례에 맞습니다.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

전 assert로 왜 스마트 캐스팅이 안되죠,,

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

음? 그럼 혹시 assertTrue(effect is BookmarkSideEffect.NavigateToPdf) 로 해보시겠어요?
그래도 캐스팅이 안된다면 require를 사용하지 않은 기존의 형태로 하셔도 됩니다.

viewModel.sideEffect.test {
awaitItem().also {
assert(it is BookmarkSideEffect.NavigateToPdf)
assert((it as BookmarkSideEffect.NavigateToPdf).path == file.path)
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

assertEquals를 사용하면 의미를 더 정확하게 표현할 수 있습니다.
값 검증을 위한 다양한 assert가 있으니 활용해보면 좋겠습니다.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

다음 PR에서 수정했습니다

Copy link

Quality Gate Failed Quality Gate failed

Failed conditions
29.5% Duplication on New Code (required ≤ 3%)

See analysis details on SonarQube Cloud

Copy link

@f-lab-dean f-lab-dean left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM,
require 부분만 변경하시고 머지하셔도 좋습니다.

@@ -26,7 +26,8 @@ class ExploreViewModelTest {

private lateinit var viewModel: ExploreViewModel

private val recentRepository = TestRecentRepository()
@MockK
private lateinit var recentRepository: RecentRepository

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

테스트 코드 작성에 관하여 고전파와 런던파 두 가지의 형태가 있습니다.
이러한 차이는 모킹에 대해서 발생하는 부분도 있습니다.
수정하실 필요는 없고, 인터페이스를 모킹을 하는것과 테스트용 구현체를 만들어 테스트 하는 것 두 가지에 대해 나름대로의 의견을 정리해보시면 좋을 것 같아요.

그리고 Kotest의 경우는 Mockk와 함께 사용하면 성능저하가 발생하기도 합니다.
(모킹은 테스트코드 빌드 시간을 오래 걸리게 만드는 요소 중 하나입니다.)
이런 부분에서 오는 장단점도 고려할 수 있다면 더 좋겠습니다.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants