Skip to content

Commit

Permalink
Step4. Use Dagger
Browse files Browse the repository at this point in the history
- Updated Dagger version due to bug[google/dagger#3032]
  • Loading branch information
dkghazz committed Dec 8, 2022
1 parent 1ad5eac commit 8b1c92b
Show file tree
Hide file tree
Showing 10 changed files with 121 additions and 49 deletions.
13 changes: 11 additions & 2 deletions app/build.gradle
Expand Up @@ -41,8 +41,14 @@ dependencies {
implementation "io.reactivex.rxjava2:rxandroid:2.1.1"

// Dagger2
implementation "com.google.dagger:dagger:2.38.1"
kapt "com.google.dagger:dagger-compiler:2.38.1"
implementation "com.google.dagger:dagger:2.44.2"
implementation 'io.mockk:mockk-android:1.13.3'
testImplementation 'junit:junit:4.12'
kapt "com.google.dagger:dagger-compiler:2.44.2"
implementation "com.google.dagger:dagger-android:2.44.2"
kapt "com.google.dagger:dagger-android-processor:2.44.2"
implementation "com.google.dagger:dagger-android-support:2.44.2"
kapt "com.google.dagger:dagger-android-support:2.44.2"

// Retrofit
implementation "com.squareup.retrofit2:retrofit:2.9.0"
Expand All @@ -58,4 +64,7 @@ dependencies {
testImplementation 'junit:junit:4.13.2'
androidTestImplementation 'androidx.test.ext:junit:1.1.3'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'
testImplementation "androidx.test.ext:junit-ktx:1.1.3"
testImplementation "androidx.test:core-ktx:1.4.0"
testImplementation "org.robolectric:robolectric:4.4"
}
25 changes: 0 additions & 25 deletions app/src/main/java/com/buzzvil/onboarding/Container.kt

This file was deleted.

8 changes: 6 additions & 2 deletions app/src/main/java/com/buzzvil/onboarding/MyApplication.kt
@@ -1,11 +1,15 @@
package com.buzzvil.onboarding

import android.app.Application
import com.buzzvil.onboarding.di.AppComponent
import com.buzzvil.onboarding.di.DaggerAppComponent

class MyApplication : Application() {
lateinit var container: Container
var appComponent: AppComponent? = null
override fun onCreate() {
super.onCreate()
container = Container()
appComponent = DaggerAppComponent.builder()
.appContext(this)
.build()
}
}
Expand Up @@ -2,13 +2,10 @@ package com.buzzvil.onboarding.data

import com.buzzvil.onboarding.domain.model.Ad
import com.buzzvil.onboarding.domain.repository.AdRepository
import com.google.gson.Gson
import io.reactivex.Single
import retrofit2.Retrofit
import retrofit2.adapter.rxjava2.RxJava2CallAdapterFactory
import retrofit2.converter.gson.GsonConverterFactory
import javax.inject.Inject

class AdRepositoryImpl(private val buzzAdApi: BuzzAdApi) : AdRepository {
class AdRepositoryImpl @Inject constructor(private val buzzAdApi: BuzzAdApi) : AdRepository {
override fun fetchAd(): Single<Ad> {
return buzzAdApi.get()
}
Expand Down
21 changes: 21 additions & 0 deletions app/src/main/java/com/buzzvil/onboarding/di/AppComponent.kt
@@ -0,0 +1,21 @@
package com.buzzvil.onboarding.di

import android.content.Context
import com.buzzvil.onboarding.presentation.MainActivity
import dagger.BindsInstance
import dagger.Component

@Component(modules = [
NetworkModule::class
])
interface AppComponent {
fun inject(mainActivity: MainActivity)

@Component.Builder
interface Builder {
fun build(): AppComponent

@BindsInstance
fun appContext(context: Context): Builder
}
}
36 changes: 36 additions & 0 deletions app/src/main/java/com/buzzvil/onboarding/di/NetworkModule.kt
@@ -0,0 +1,36 @@
package com.buzzvil.onboarding.di

import com.buzzvil.onboarding.data.AdRepositoryImpl
import com.buzzvil.onboarding.data.BuzzAdApi
import com.buzzvil.onboarding.domain.repository.AdRepository
import com.google.gson.Gson
import dagger.Binds
import dagger.Module
import dagger.Provides
import retrofit2.Retrofit
import retrofit2.adapter.rxjava2.RxJava2CallAdapterFactory
import retrofit2.converter.gson.GsonConverterFactory

@Module
abstract class NetworkModule {
@Binds
abstract fun bindsAdRepository(repositoryImpl: AdRepositoryImpl): AdRepository

companion object {
@Provides
fun providesGson(): Gson = Gson().newBuilder()
.setLenient()
.create()

@Provides
fun providesRetrofit(gson: Gson): Retrofit = Retrofit.Builder()
.baseUrl("https://s3-ap-northeast-1.amazonaws.com/buzzvi.test/")
.addConverterFactory(GsonConverterFactory.create(gson))
.addCallAdapterFactory(RxJava2CallAdapterFactory.create())
.build()

@Provides
fun providesBuzzAdApi(retrofit: Retrofit): BuzzAdApi =
retrofit.create(BuzzAdApi::class.java)
}
}
Expand Up @@ -3,8 +3,9 @@ package com.buzzvil.onboarding.domain.usecase
import com.buzzvil.onboarding.domain.model.Ad
import com.buzzvil.onboarding.domain.repository.AdRepository
import io.reactivex.Single
import javax.inject.Inject

class FetchAd (private val adRepository: AdRepository) {
class FetchAd @Inject constructor(private val adRepository: AdRepository) {
operator fun invoke(): Single<Ad> {
return adRepository.fetchAd()
}
Expand Down
Expand Up @@ -2,36 +2,34 @@ package com.buzzvil.onboarding.presentation

import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import com.buzzvil.onboarding.Container
import com.buzzvil.onboarding.MyApplication
import com.buzzvil.onboarding.databinding.ActivityMainBinding
import com.buzzvil.onboarding.domain.repository.AdRepository
import com.buzzvil.onboarding.domain.usecase.FetchAd
import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.disposables.CompositeDisposable
import io.reactivex.schedulers.Schedulers
import javax.inject.Inject

class MainActivity : AppCompatActivity() {
companion object {
const val TAG = "MAIN_ACTIVITY"
}

private lateinit var viewModel: MainViewModel
private lateinit var fetchAd: FetchAd
@Inject
lateinit var viewModel: MainViewModel
private lateinit var binding: ActivityMainBinding

override fun onCreate(savedInstanceState: Bundle?) {
(applicationContext as MyApplication).appComponent?.inject(this)

super.onCreate(savedInstanceState)
binding = ActivityMainBinding.inflate(layoutInflater)
setContentView(binding.root)

inject((application as MyApplication).container)
viewModel = MainViewModel(fetchAd)
observeViewState()
}

override fun onResume() {
super.onResume()
loadViewState()
// loadViewState() // NOTE: 필요한 경우 (Ex. Resume이 되었을 때, update가 필요한 경우에만 사용)
}

private fun loadViewState() {
Expand All @@ -51,8 +49,4 @@ class MainActivity : AppCompatActivity() {
private fun handleViewState(viewState: MainViewModel.ViewState) {
binding.textView.text = viewState.text
}

private fun inject(container: Container) {
fetchAd = container.fetchAd
}
}
Expand Up @@ -7,8 +7,9 @@ import com.buzzvil.onboarding.domain.usecase.FetchAd
import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.disposables.CompositeDisposable
import io.reactivex.schedulers.Schedulers
import javax.inject.Inject

class MainViewModel(private val fetchAd: FetchAd) : ViewModel() {
class MainViewModel @Inject constructor(private val fetchAd: FetchAd) : ViewModel() {
data class ViewState(val text: String = "")

private val compositeDisposable = CompositeDisposable()
Expand Down
@@ -0,0 +1,34 @@
package com.buzzvil.onboarding.presentation

import androidx.test.ext.junit.runners.AndroidJUnit4
import com.buzzvil.onboarding.domain.model.Ad
import com.buzzvil.onboarding.domain.usecase.FetchAd
import io.mockk.every
import io.mockk.mockk
import io.mockk.verify
import io.reactivex.Single
import org.junit.Assert.*
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith

@RunWith(AndroidJUnit4::class)
class MainViewModelTest {
private lateinit var fetchAd: FetchAd
private lateinit var mainViewModel: MainViewModel

@Before
fun setUp() {
fetchAd = mockk()
}

@Test
fun `test 111`() {
every {
fetchAd()
} returns Single.just(Ad(listOf()))
mainViewModel = MainViewModel(fetchAd)

verify { fetchAd() }
}
}

0 comments on commit 8b1c92b

Please sign in to comment.