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

Write Test Code In 'core.domain' package #1359

Open
wants to merge 16 commits into
base: main
Choose a base branch
from

Conversation

squart300kg
Copy link
Contributor

@squart300kg squart300kg commented Apr 3, 2024

[What I have done and why]
write test code named 'GetRecentSearchQueriesUseCaseTest' in 'core.comain' package

[why i have done]
JoseAlcerreca raised issue numbered #1327.

[note]
#1327 issue completion need to write 3 class test code additionaly. Firstly, i write one class of them. so If this code is appropriate and merged, i will try one pull request containing the rest of 2 class test code.

if this code is inappropriate, please feed back for me. I will gladly accept your opinion. Thanks : )

Fixes #1327

How I'm testing it

Choose at least one:

  • Unit tests
  • UI tests
  • Screenshot tests
  • N/A (provide justification)

Do tests pass?

  • Run local tests on DemoDebug variant: ./gradlew testDemoDebug
  • Check formatting: ./gradlew --init-script gradle/init.gradle.kts spotlessApply

Is this your first pull request?

for (index in 0 until 5) {
recentSearchRepository.insertOrReplaceRecentSearch(testRecentSearchQueries[index])
// delay for saving value
delay(10L)
Copy link
Contributor

Choose a reason for hiding this comment

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

we shouldn't rely on timing in unit tests. It's an in-memory cache, why do you need the delay in the first place?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

In the loop for saving search queries, there is an issue where the sequence of the saved values is not maintained in order. I hypothesized that the problem might be due to the timing of saving values multiple times.

Therefore, I applied a delay of 10 milliseconds. and so, i resolve for timing issue.

If there are any issues with this approach, I would appreciate your review.

import org.junit.Test
import kotlin.test.assertEquals

class GetRecentSearchQueriesUseCaseTest {
Copy link
Contributor

Choose a reason for hiding this comment

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

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Thanks. i will check this convention.

val recentSearchQueries = useCase()

// insert 5 search queries.
for (index in 0 until 5) {
Copy link
Contributor

Choose a reason for hiding this comment

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

testRecentSearchQueries.take(5).forEach

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I realized that the loop type of 'forEach' is mainly used exceping for 'for (item in items)' type. i will use these type from now on :)

recentSearchQueries.first().map { it.query },
)

// insert 9 more search queries.
Copy link
Contributor

Choose a reason for hiding this comment

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

any reason to do this again? I think this should be in a different test

Copy link
Contributor Author

Choose a reason for hiding this comment

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

after careful consideration, it is correct for deleting this code. :)

)

@Test
fun whenNoParams_recentSearchQueriesAreReturnedUpTo10() = runTest {
Copy link
Contributor

Choose a reason for hiding this comment

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

Params should be replaced by its actual name, which is "limit"

Copy link
Contributor Author

Choose a reason for hiding this comment

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

yes, your opinion is more reasonable. but, test code naming convention(='whenNoParams_followableTopicsAreReturnedWithNoSorting' in 'GetFollowableTopicsUseCaseTest') is not correct.

so according to what you said, is it correct that this method name should also be modified? if yes, i will try one of them.

  1. Modifying the method name of 'whenNoParams_followableTopicsAreReturnedWithNoSorting' together and pull request.
  2. Register as another issue and proceed.
  3. Or, is there a reason to maintain the name?

// Obtain a stream of recent search queries with param set 5.
val recentSearchQueries = useCase(5)

// insert 2 search queries.
Copy link
Contributor

Choose a reason for hiding this comment

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

this is already tested in a previous test, can be removed

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Regardless of parameter injection, after thinking about it again, I think the test logic is duplicate.


class TestRecentSearchRepository : RecentSearchRepository {

private val cachedRecentSearches: MutableList<RecentSearchQuery> = mutableListOf()

override fun getRecentSearchQueries(limit: Int): Flow<List<RecentSearchQuery>> =
flowOf(cachedRecentSearches.sortedByDescending { it.queriedDate }.take(limit))
Copy link
Contributor

Choose a reason for hiding this comment

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

is this change necessary?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

yes, i think that this code need to be changed. because the flow producers such as 'flowOf' and 'flow { emit() }' have different in emitting updated list. and although one depth inner code is same when emitting data by 'flow { emit() }, two depth inner code is different. because of this, i realized that the way of data emitting can not be same.

[two depth inner code]
스크린샷 2024-04-04 오전 10 49 00
left : flow { emit() } / right : flowOf()
additional reference, my blog column(lang korean) : different between flowOf and flow { emit() }

because of this change, i had tested 'SearchViewModelTest' and passed. so, i think that this change is reasonable.

how about your opinion? :)

Change-Id: Ia1d9049642e447d9233713a7e3ee593d0bd56930
Change-Id: I2a818503cffc458085e7aee04c2c12d9df532b3c
android#1327])

Change-Id: I392a1e3ebcbc8bc30623559d97c1657e5d50fbbc
…squart300kg/nowinandroid into Issue1327/ImproveDomainCoverage

Change-Id: I9a779a4d11230dd849d1e961d3e572fc13c2002c
@squart300kg
Copy link
Contributor Author

squart300kg commented Apr 5, 2024

@JoseAlcerreca
I acceped your feedback and pull request again. so, when you have time, I would like you to review my updated code.

Thanks : )

@@ -19,14 +19,16 @@ package com.google.samples.apps.nowinandroid.core.testing.repository
import com.google.samples.apps.nowinandroid.core.data.model.RecentSearchQuery
import com.google.samples.apps.nowinandroid.core.data.repository.RecentSearchRepository
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.flowOf
import kotlinx.coroutines.flow.flow

class TestRecentSearchRepository : RecentSearchRepository {

private val cachedRecentSearches: MutableList<RecentSearchQuery> = mutableListOf()
Copy link
Contributor

Choose a reason for hiding this comment

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

How about using MutableSharedFlow like another TestRepository? :)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@yongsuk44 I agree with your opinion. but because i didn't fully understand using 'MutableList' instead of "MutableSahredFlow' like other unit test code, i did not change this code.

and the primary purpose of this 'PR' is writing the test code of 'UseCase' class in domain layer. :)

i have thought that your opinion is reasonable so far 👍

Copy link
Contributor

Choose a reason for hiding this comment

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

@squart300kg
I've determined that handling test cases reactively when utilizing this repository in the future would likely lead to a smoother process. Hence, I've left a comment to that effect. :)

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.

[Testing FR] [core:domain] Improve coverage
4 participants