-
Notifications
You must be signed in to change notification settings - Fork 1
feat: domain model 테스트 코드 작성 #798
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
Changes from all commits
6f38b38
994931b
7b07cf8
7329f57
1c06214
97fc602
c352f56
cd6dc59
57822da
9804de8
1c05a89
590f8d5
0bf9893
8b1fc3c
579be2d
0da029c
cd00490
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,87 @@ | ||
| package com.into.websoso.domain.usecase | ||
|
|
||
| import com.into.websoso.data.model.ExploreResultEntity | ||
| import com.into.websoso.data.repository.NovelRepository | ||
| import io.mockk.clearMocks | ||
| import io.mockk.coEvery | ||
| import io.mockk.coVerify | ||
| import io.mockk.mockk | ||
| import kotlinx.coroutines.test.runTest | ||
| import org.junit.Before | ||
| import org.junit.Test | ||
|
|
||
| class GetSearchedNovelsUseCaseTest { | ||
| private lateinit var getSearchedNovelsUseCase: GetSearchedNovelsUseCase | ||
| private val novelRepository: NovelRepository = mockk(relaxed = true) | ||
|
|
||
| private val dummyExploreResultEntity = ExploreResultEntity( | ||
| resultCount = 0L, | ||
| isLoadable = true, | ||
| novels = emptyList(), | ||
| ) | ||
|
|
||
| @Before | ||
| fun setUp() { | ||
| getSearchedNovelsUseCase = GetSearchedNovelsUseCase(novelRepository) | ||
| coEvery { | ||
| novelRepository.fetchNormalExploreResult( | ||
| any(), | ||
| any(), | ||
| any(), | ||
| ) | ||
| } returns dummyExploreResultEntity | ||
| } | ||
|
|
||
| @Test | ||
| fun `처음 검색하면 페이지는 0, 사이즈는 20으로 레포지토리에 요청한다`() = | ||
| runTest { | ||
| // when | ||
| getSearchedNovelsUseCase("웹소설") | ||
|
|
||
| // then | ||
|
|
||
| coVerify(exactly = 1) { | ||
| novelRepository.fetchNormalExploreResult( | ||
| searchWord = "웹소설", | ||
| page = 0, | ||
| size = 20, | ||
| ) | ||
| } | ||
| } | ||
|
|
||
| @Test | ||
| fun `같은 검색어로 다시 검색하면 페이지는 1, 사이즈는 10으로 레포지토리에 요청한다`() = | ||
| runTest { | ||
| // when | ||
| getSearchedNovelsUseCase("웹소설") // 0페이지 20개 | ||
| getSearchedNovelsUseCase("웹소설") // 1페이지 10개 | ||
|
|
||
| // then | ||
| coVerify(exactly = 1) { | ||
| novelRepository.fetchNormalExploreResult( | ||
| searchWord = "웹소설", | ||
| page = 1, | ||
| size = 10, | ||
| ) | ||
| } | ||
| } | ||
|
|
||
| @Test | ||
| fun `다른 검색어로 검색하면 캐시를 지우고 페이지는 0으로 레포지토리에 요청한다`() = | ||
| runTest { | ||
| // when | ||
| getSearchedNovelsUseCase("웹소설") // clear 1회 | ||
| clearMocks(novelRepository, answers = false) | ||
| getSearchedNovelsUseCase("새로운 웹소설") | ||
|
|
||
| // then | ||
| coVerify(exactly = 1) { | ||
| novelRepository.clearCachedNormalExploreResult() | ||
| novelRepository.fetchNormalExploreResult( | ||
| searchWord = "새로운 웹소설", | ||
| page = 0, | ||
| size = 20, | ||
| ) | ||
| } | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,69 @@ | ||
| package com.into.websoso.domain.library.model | ||
|
|
||
| import com.into.websoso.domain.library.model.AttractivePoints.Companion.toAttractivePoints | ||
| import org.junit.Assert.assertEquals | ||
| import org.junit.Assert.assertFalse | ||
| import org.junit.Assert.assertTrue | ||
| import org.junit.Test | ||
|
|
||
| class AttractivePointsTest { | ||
| @Test | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. c: 이 아래로 gwt주석이 없는데, 유즈케이스 테스트랑 코드 스타일이 통일되면 좋을 것 같아요 주석이 다 있거나 아예 다 없거나!
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 주석 없는 테스트 케이스 모두 gwt으로 통일하였습니다! |
||
| fun `기본 상태에서는 아무 항목도 선택되지 않는다`() { | ||
| // given | ||
| val points = AttractivePoints() | ||
|
|
||
| // then | ||
| assertFalse(points.isSelected) | ||
| assertTrue(points.selectedAttractivePoints.isEmpty()) | ||
| assertTrue(points.selectedLabels.isEmpty()) | ||
| assertTrue(points.selectedKeys.isEmpty()) | ||
|
|
||
| for (point in AttractivePoint.entries) { | ||
| assertFalse(points[point]) | ||
| } | ||
| } | ||
|
|
||
| @Test | ||
| fun `항목을 선택하면 해당 항목만 선택 상태가 된다`() { | ||
| // given | ||
| val points = AttractivePoints() | ||
|
|
||
| // when | ||
| val selected = points.set(AttractivePoint.WORLDVIEW) | ||
|
|
||
| // then | ||
| assertTrue(selected[AttractivePoint.WORLDVIEW]) | ||
| assertTrue(selected.isSelected) | ||
| assertEquals(listOf("세계관"), selected.selectedLabels) | ||
| assertEquals(listOf("worldview"), selected.selectedKeys) | ||
| } | ||
|
|
||
| @Test | ||
| fun `같은 항목을 다시 선택하면 선택이 해제된다`() { | ||
| // given | ||
| val points = AttractivePoints() | ||
|
|
||
| // when | ||
| val toggled = points | ||
| .set(AttractivePoint.WORLDVIEW) | ||
| .set(AttractivePoint.WORLDVIEW) | ||
|
|
||
| // then | ||
| assertFalse(toggled[AttractivePoint.WORLDVIEW]) | ||
| assertFalse(toggled.isSelected) | ||
| } | ||
|
|
||
| @Test | ||
| fun `문자열 키 목록을 통해 선택 상태를 생성할 수 있다`() { | ||
| // given | ||
| val keys = listOf("worldview", "character", "unknown") | ||
|
|
||
| // when | ||
| val points = keys.toAttractivePoints() | ||
|
|
||
| // then | ||
| assertTrue(points[AttractivePoint.WORLDVIEW]) | ||
| assertTrue(points[AttractivePoint.CHARACTER]) | ||
| assertFalse(points[AttractivePoint.MATERIAL]) | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,56 @@ | ||
| package com.into.websoso.domain.library.model | ||
|
|
||
| import org.junit.Assert.assertEquals | ||
| import org.junit.Assert.assertFalse | ||
| import org.junit.Assert.assertTrue | ||
| import org.junit.Test | ||
|
|
||
| class NovelRatingTest { | ||
| @Test | ||
| fun `기본 평점은 선택되지 않은 상태이다`() { | ||
| // given | ||
| val rating = NovelRating() | ||
|
|
||
| // then | ||
| assertEquals(Rating.DEFAULT, rating.rating) | ||
| assertFalse(rating.isSelected) | ||
| } | ||
|
|
||
| @Test | ||
| fun `평점을 설정하면 선택 상태가 된다`() { | ||
| // given | ||
| val input = 4.0f | ||
|
|
||
| // when | ||
| val rating = NovelRating.from(input) | ||
|
|
||
| // then | ||
| assertTrue(rating.isSelected) | ||
| assertEquals(Rating.FOUR, rating.rating) | ||
| } | ||
|
|
||
| @Test | ||
| fun `같은 평점을 다시 설정하면 기본 상태로 돌아간다`() { | ||
| // given | ||
| val rating = NovelRating.from(3.0f) | ||
|
|
||
| // when | ||
| val toggled = rating.set(Rating.THREE) | ||
|
|
||
| // then | ||
| assertEquals(Rating.DEFAULT, toggled.rating) | ||
| assertFalse(toggled.isSelected) | ||
| } | ||
|
|
||
| @Test | ||
| fun `평점은 근사값 비교로 판단된다`() { | ||
| // given | ||
| val rating = NovelRating.from(4.0f) | ||
|
|
||
| // when | ||
| val result = rating.isCloseTo(Rating.from(4.00001f)) | ||
|
|
||
| // then | ||
| assertTrue(result) | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,47 @@ | ||||||||||||||||||||||||||||||||||||||||||||||
| package com.into.websoso.domain.library.model | ||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||
| import org.junit.Assert.assertEquals | ||||||||||||||||||||||||||||||||||||||||||||||
| import org.junit.Test | ||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||
| class RatingTest { | ||||||||||||||||||||||||||||||||||||||||||||||
| @Test | ||||||||||||||||||||||||||||||||||||||||||||||
| fun `정확한 값은 대응되는 평점으로 변환된다`() { | ||||||||||||||||||||||||||||||||||||||||||||||
| // when | ||||||||||||||||||||||||||||||||||||||||||||||
| val default = Rating.from(0.0f) | ||||||||||||||||||||||||||||||||||||||||||||||
| val one = Rating.from(1.0f) | ||||||||||||||||||||||||||||||||||||||||||||||
| val threePointFive = Rating.from(3.5f) | ||||||||||||||||||||||||||||||||||||||||||||||
| val fourPointEight = Rating.from(4.8f) | ||||||||||||||||||||||||||||||||||||||||||||||
| val five = Rating.from(5.0f) | ||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||
| // then | ||||||||||||||||||||||||||||||||||||||||||||||
| assertEquals(Rating.DEFAULT, default) | ||||||||||||||||||||||||||||||||||||||||||||||
| assertEquals(Rating.ONE, one) | ||||||||||||||||||||||||||||||||||||||||||||||
| assertEquals(Rating.THREE_POINT_FIVE, threePointFive) | ||||||||||||||||||||||||||||||||||||||||||||||
| assertEquals(Rating.FOUR_POINT_EIGHT, fourPointEight) | ||||||||||||||||||||||||||||||||||||||||||||||
| assertEquals(Rating.FIVE, five) | ||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||
| @Test | ||||||||||||||||||||||||||||||||||||||||||||||
| fun `근사값도 가까운 평점으로 변환된다`() { | ||||||||||||||||||||||||||||||||||||||||||||||
| // when | ||||||||||||||||||||||||||||||||||||||||||||||
| val four = Rating.from(4.00001f) | ||||||||||||||||||||||||||||||||||||||||||||||
| val fourPointEight = Rating.from(4.79999f) | ||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||
| // then | ||||||||||||||||||||||||||||||||||||||||||||||
| assertEquals(Rating.FOUR, four) | ||||||||||||||||||||||||||||||||||||||||||||||
| assertEquals(Rating.FOUR_POINT_EIGHT, fourPointEight) | ||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||
| @Test | ||||||||||||||||||||||||||||||||||||||||||||||
| fun `매칭되지 않는 값은 기본 평점으로 처리된다`() { | ||||||||||||||||||||||||||||||||||||||||||||||
| // when | ||||||||||||||||||||||||||||||||||||||||||||||
| val negative = Rating.from(-1.0f) | ||||||||||||||||||||||||||||||||||||||||||||||
| val unmatched = Rating.from(4.7f) | ||||||||||||||||||||||||||||||||||||||||||||||
| val overflow = Rating.from(100.0f) | ||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||
| // then | ||||||||||||||||||||||||||||||||||||||||||||||
| assertEquals(Rating.DEFAULT, negative) | ||||||||||||||||||||||||||||||||||||||||||||||
| assertEquals(Rating.DEFAULT, unmatched) | ||||||||||||||||||||||||||||||||||||||||||||||
| assertEquals(Rating.DEFAULT, overflow) | ||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+36
to
+46
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Line 37의 🛠️ 수정 제안 fun `매칭되지 않는 값은 기본 평점으로 처리된다`() {
-// when
+ // when
val negative = Rating.from(-1.0f)📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,67 @@ | ||
| package com.into.websoso.domain.library.model | ||
|
|
||
| import com.into.websoso.domain.library.model.ReadStatuses.Companion.toReadStatuses | ||
| import org.junit.Assert.assertEquals | ||
| import org.junit.Assert.assertFalse | ||
| import org.junit.Assert.assertTrue | ||
| import org.junit.Test | ||
|
|
||
| class ReadStatusesTest { | ||
| @Test | ||
| fun `기본 상태에서는 아무 상태도 선택되지 않는다`() { | ||
| // given | ||
| val statuses = ReadStatuses() | ||
|
|
||
| // then | ||
| assertFalse(statuses.isSelected) | ||
| assertTrue(statuses.selectedKeys.isEmpty()) | ||
| assertTrue(statuses.selectedLabels.isEmpty()) | ||
|
|
||
| for (status in ReadStatus.entries) { | ||
| assertFalse(statuses[status]) | ||
| } | ||
| } | ||
|
|
||
| @Test | ||
| fun `읽기 상태를 선택하면 해당 상태가 선택된다`() { | ||
| // given | ||
| val statuses = ReadStatuses() | ||
|
|
||
| // when | ||
| val selected = statuses.set(ReadStatus.WATCHING) | ||
|
|
||
| // then | ||
| assertTrue(selected[ReadStatus.WATCHING]) | ||
| assertTrue(selected.isSelected) | ||
| assertEquals(listOf("WATCHING"), selected.selectedKeys) | ||
| } | ||
|
|
||
| @Test | ||
| fun `같은 읽기 상태를 다시 선택하면 선택이 해제된다`() { | ||
| // given | ||
| val statuses = ReadStatuses() | ||
|
|
||
| // when | ||
| val toggled = statuses | ||
| .set(ReadStatus.WATCHING) | ||
| .set(ReadStatus.WATCHING) | ||
|
|
||
| // then | ||
| assertFalse(toggled[ReadStatus.WATCHING]) | ||
| assertFalse(toggled.isSelected) | ||
| } | ||
|
|
||
| @Test | ||
| fun `문자열 키 목록으로 읽기 상태를 생성할 수 있다`() { | ||
| // given | ||
| val keys = listOf("WATCHING", "QUIT", "UNKNOWN") | ||
|
|
||
| // when | ||
| val statuses = keys.toReadStatuses() | ||
|
|
||
| // then | ||
| assertTrue(statuses[ReadStatus.WATCHING]) | ||
| assertTrue(statuses[ReadStatus.QUIT]) | ||
| assertFalse(statuses[ReadStatus.WATCHED]) | ||
| } | ||
| } |
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.
c: 앞으로 테스트를 어느범위까지 적용시킬 생각이신가요?
범위에 따라 테스트 의존성을 플러그인에 추가해도 좋을 것 같아서요
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.
현재는 도메인 레이어 모델과 하나의 UseCase에 대해서만 로컬 유닛 테스트를 작성한 상태입니다.
추후 테스트 범위가 확장될 경우에는 의존성 관리 방식도 함께 정리하여, 모듈별 개별 추가보다는 공통 플러그인으로 관리하는 방향을 고려하겠습니다..!