Skip to content

Commit

Permalink
PracticeA3-통합 테스트 맛보기 (Test Double, Hilt)
Browse files Browse the repository at this point in the history
  • Loading branch information
cliearl committed Jul 23, 2022
1 parent 6f3e56a commit ee56a84
Show file tree
Hide file tree
Showing 7 changed files with 162 additions and 12 deletions.
8 changes: 6 additions & 2 deletions app/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,8 @@ android {
versionCode = DefaultConfig.VERSION_CODE
versionName = DefaultConfig.VERSION_NAME

testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
// testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
testInstrumentationRunner = "com.qualitybitz.booksearchapp.HiltTestRunner"
}

buildTypes {
Expand Down Expand Up @@ -65,14 +66,17 @@ dependencies {
testImplementation("org.robolectric:robolectric:4.8.1")
testImplementation("androidx.test.ext:junit:1.1.3")
testImplementation("androidx.test:core:1.4.0")
testImplementation("org.jetbrains.kotlinx:kotlinx-coroutines-test:1.6.2")

androidTestImplementation(Testing.ANDROID_JUNIT)
androidTestImplementation(Testing.ESPRESSO_CORE)
androidTestImplementation("androidx.test:core:1.4.0") // Test Core
androidTestImplementation("androidx.test.ext:truth:1.4.0")
androidTestImplementation("androidx.test:runner:1.4.0")
androidTestImplementation("org.jetbrains.kotlinx:kotlinx-coroutines-test:1.6.2")

androidTestImplementation("com.google.dagger:hilt-android-testing:2.41")
kaptAndroidTest("com.google.dagger:hilt-android-compiler:2.41")

// Retrofit
implementation(Dependencies.RETROFIT)
implementation(Dependencies.RETROFIT_CONVERTER_MOSHI)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package com.qualitybitz.booksearchapp

import android.app.Application
import android.content.Context
import androidx.test.runner.AndroidJUnitRunner
import dagger.hilt.android.testing.HiltTestApplication

class HiltTestRunner : AndroidJUnitRunner() {

override fun newApplication(
cl: ClassLoader?,
className: String?,
context: Context?
): Application {
return super.newApplication(cl, HiltTestApplication::class.java.name, context)
}
}
Original file line number Diff line number Diff line change
@@ -1,33 +1,42 @@
package com.qualitybitz.booksearchapp.data.db

import androidx.room.Room
import androidx.test.core.app.ApplicationProvider
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.google.common.truth.Truth.assertThat
import com.qualitybitz.booksearchapp.data.model.Book
import dagger.hilt.android.testing.HiltAndroidRule
import dagger.hilt.android.testing.HiltAndroidTest
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.flow.first
import kotlinx.coroutines.test.runTest
import org.junit.After
import org.junit.Before
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
import javax.inject.Inject
import javax.inject.Named

@RunWith(AndroidJUnit4::class)
//@RunWith(AndroidJUnit4::class)
@HiltAndroidTest
@SmallTest
@ExperimentalCoroutinesApi
class BookSearchDaoTest {

private lateinit var database: BookSearchDatabase
// private lateinit var database: BookSearchDatabase
@Inject
@Named("test_db")
lateinit var database: BookSearchDatabase
private lateinit var dao: BookSearchDao

@get:Rule
var hiltRule = HiltAndroidRule(this)

@Before
fun setUp() {
database = Room.inMemoryDatabaseBuilder(
ApplicationProvider.getApplicationContext(),
BookSearchDatabase::class.java
).allowMainThreadQueries().build()
// database = Room.inMemoryDatabaseBuilder(
// ApplicationProvider.getApplicationContext(),
// BookSearchDatabase::class.java
// ).allowMainThreadQueries().build()
hiltRule.inject()
dao = database.bookSearchDao()
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package com.qualitybitz.booksearchapp.di

import android.content.Context
import androidx.room.Room
import com.qualitybitz.booksearchapp.data.db.BookSearchDatabase
import dagger.Module
import dagger.Provides
import dagger.hilt.InstallIn
import dagger.hilt.android.qualifiers.ApplicationContext
import dagger.hilt.components.SingletonComponent
import javax.inject.Named

@Module
@InstallIn(SingletonComponent::class)
object TestAppModule {

@Provides
@Named("test_db")
fun provideInMemoryDb(@ApplicationContext context: Context): BookSearchDatabase =
Room.inMemoryDatabaseBuilder(context, BookSearchDatabase::class.java)
.allowMainThreadQueries()
.build()
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import com.qualitybitz.booksearchapp.data.model.Book
import com.qualitybitz.booksearchapp.data.repository.BookSearchRepository
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.launch
import javax.inject.Inject

Expand All @@ -18,4 +19,7 @@ class BookViewModel @Inject constructor(
fun saveBook(book: Book) = viewModelScope.launch(Dispatchers.IO) {
bookSearchRepository.insertBooks(book)
}

// For test
val favoriteBooks: Flow<List<Book>> = bookSearchRepository.getFavoriteBooks()
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
package com.qualitybitz.booksearchapp.data.repository

import androidx.paging.PagingData
import com.qualitybitz.booksearchapp.data.model.Book
import com.qualitybitz.booksearchapp.data.model.SearchResponse
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.flowOf
import retrofit2.Response

class FakeBookSearchRepository : BookSearchRepository {

private val bookItems = mutableListOf<Book>()

override suspend fun searchBooks(
query: String,
sort: String,
page: Int,
size: Int
): Response<SearchResponse> {
TODO("Not yet implemented")
}

override suspend fun insertBooks(book: Book) {
bookItems.add(book)
}

override suspend fun deleteBooks(book: Book) {
bookItems.remove(book)
}

override fun getFavoriteBooks(): Flow<List<Book>> {
return flowOf(bookItems)
}

override suspend fun saveSortMode(mode: String) {
TODO("Not yet implemented")
}

override suspend fun getSortMode(): Flow<String> {
TODO("Not yet implemented")
}

override suspend fun saveCacheDeleteMode(mode: Boolean) {
TODO("Not yet implemented")
}

override suspend fun getCacheDeleteMode(): Flow<Boolean> {
TODO("Not yet implemented")
}

override fun getFavoritePagingBooks(): Flow<PagingData<Book>> {
TODO("Not yet implemented")
}

override fun searchBooksPaging(query: String, sort: String): Flow<PagingData<Book>> {
TODO("Not yet implemented")
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package com.qualitybitz.booksearchapp.ui.viewmodel

import androidx.test.filters.MediumTest
import com.google.common.truth.Truth
import com.qualitybitz.booksearchapp.data.model.Book
import com.qualitybitz.booksearchapp.data.repository.FakeBookSearchRepository
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.flow.first
import kotlinx.coroutines.test.runTest
import org.junit.Before
import org.junit.Test

@ExperimentalCoroutinesApi
@MediumTest
class BookViewModelTest {

private lateinit var viewModel: BookViewModel

@Before
fun setUp() {
viewModel = BookViewModel(FakeBookSearchRepository())
}

@Test
fun save_book_test() = runTest {
val book = Book(
listOf("a"), "b", "c", "d", 0, "e",
0, "f", "g", "h", listOf("i"), "j"
)
viewModel.saveBook(book)

val favoriteBooks = viewModel.favoriteBooks.first()
Truth.assertThat(favoriteBooks).contains(book)
}
}

0 comments on commit ee56a84

Please sign in to comment.