diff --git a/app/build.gradle.kts b/app/build.gradle.kts
index a687cd2d79b6e52ff87a0a964b7619cd244299b2..c74673ca22d6b4da75c5de4689b785facffeb2dd 100644
--- a/app/build.gradle.kts
+++ b/app/build.gradle.kts
@@ -88,6 +88,7 @@ dependencies {
     val koinVersion = "3.5.3"
     implementation("io.insert-koin:koin-core:$koinVersion")
     implementation("io.insert-koin:koin-android:$koinVersion")
+    testImplementation("io.insert-koin:koin-test-junit4:$koinVersion")
 
     // Room
     val roomVersion = "2.6.1"
@@ -100,6 +101,10 @@ dependencies {
     val timberVersion = "5.0.1"
     implementation("com.jakewharton.timber:timber:$timberVersion")
 
+    // mockk
+    val mockkVersion = "1.13.10"
+    testImplementation("io.mockk:mockk:$mockkVersion")
+
     testImplementation("junit:junit:4.13.2")
     androidTestImplementation("androidx.test.ext:junit:1.1.5")
     androidTestImplementation("androidx.test.espresso:espresso-core:3.5.1")
diff --git a/app/src/main/java/com/informatika/bondoman/MainActivity.kt b/app/src/main/java/com/informatika/bondoman/MainActivity.kt
index bc87cfaa38d1b1ed626009d7e08bd61adde40a84..f0ff1371b3141acb2cc42d9b2f5e58844175d6bb 100644
--- a/app/src/main/java/com/informatika/bondoman/MainActivity.kt
+++ b/app/src/main/java/com/informatika/bondoman/MainActivity.kt
@@ -13,13 +13,15 @@ import com.google.android.material.bottomnavigation.BottomNavigationView
 import com.informatika.bondoman.databinding.ActivityMainBinding
 import com.informatika.bondoman.view.activity.LoginActivity
 import com.informatika.bondoman.prefdatastore.JWTManager
+import com.informatika.bondoman.viewmodel.JWTViewModel
 import kotlinx.coroutines.launch
+import org.koin.androidx.viewmodel.ext.android.viewModel
 
 
 class MainActivity : AppCompatActivity() {
 
     private lateinit var binding: ActivityMainBinding
-    private lateinit var jwtManager: JWTManager
+    private val jwtViewModel: JWTViewModel by viewModel()
 
     override fun onCreate(savedInstanceState: Bundle?) {
         super.onCreate(savedInstanceState)
@@ -30,8 +32,6 @@ class MainActivity : AppCompatActivity() {
         binding = ActivityMainBinding.inflate(layoutInflater)
         setContentView(binding.root)
 
-        jwtManager = JWTManager(applicationContext)
-
         val navView: BottomNavigationView = binding.navView
 
         val navController = findNavController(R.id.nav_host_fragment_activity_main)
@@ -54,8 +54,7 @@ class MainActivity : AppCompatActivity() {
         super.onStart()
 
         lifecycleScope.launch {
-            if (jwtManager.isExpired()) {
-                jwtManager.onLogout()
+            if (jwtViewModel.isExpired()) {
                 val intent = Intent(this@MainActivity, LoginActivity::class.java)
                 startActivity(intent)
                 finish()
diff --git a/app/src/main/java/com/informatika/bondoman/di/ApplicationModule.kt b/app/src/main/java/com/informatika/bondoman/di/ApplicationModule.kt
new file mode 100644
index 0000000000000000000000000000000000000000..ba6e0f378ed24cbfba23f2a2b3fddd28320ad147
--- /dev/null
+++ b/app/src/main/java/com/informatika/bondoman/di/ApplicationModule.kt
@@ -0,0 +1,17 @@
+package com.informatika.bondoman.di
+
+import com.informatika.bondoman.prefdatastore.JWTManager
+import com.squareup.moshi.Moshi
+import com.squareup.moshi.kotlin.reflect.KotlinJsonAdapterFactory
+import org.koin.android.ext.koin.androidApplication
+import org.koin.android.ext.koin.androidContext
+import org.koin.dsl.module
+
+val applicationModule = module {
+    // Dependency: Moshi
+    single<Moshi> {
+        Moshi.Builder()
+            .add(KotlinJsonAdapterFactory())
+            .build()
+    }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/informatika/bondoman/di/DatabaseModule.kt b/app/src/main/java/com/informatika/bondoman/di/DatabaseModule.kt
index 446f1b9e7500cc91bf46121220f8599d17eeed7f..561ed8fa2d157a5f8a87f881cd6b7b0f3f9b9255 100644
--- a/app/src/main/java/com/informatika/bondoman/di/DatabaseModule.kt
+++ b/app/src/main/java/com/informatika/bondoman/di/DatabaseModule.kt
@@ -1,20 +1,20 @@
 package com.informatika.bondoman.di
 
 import androidx.room.Room
-import com.informatika.bondoman.model.local.AppDB
+import com.informatika.bondoman.model.local.AppDatabase
 import com.informatika.bondoman.model.local.DBConstants
+import org.koin.android.ext.koin.androidApplication
 import org.koin.android.ext.koin.androidContext
 import org.koin.dsl.module
 
 val databaseModule = module {
     // Dependency: AppDB
     single {
-        Room.databaseBuilder(androidContext(), AppDB::class.java, DBConstants.mName).build()
+        Room.databaseBuilder(androidContext(), AppDatabase::class.java, DBConstants.mName).build()
     }
 
     // Dependency: TransactionDao
     single {
-        val appDB: AppDB = get()
-        appDB.transactionDao()
+        get<AppDatabase>().transactionDao()
     }
 }
\ No newline at end of file
diff --git a/app/src/main/java/com/informatika/bondoman/di/NetworkModule.kt b/app/src/main/java/com/informatika/bondoman/di/NetworkModule.kt
index e75873f1765de8393edf1c4c5075f5f8391b62c1..09000d567e5ec7f644315ec0c83f9fdfbc3ff654 100644
--- a/app/src/main/java/com/informatika/bondoman/di/NetworkModule.kt
+++ b/app/src/main/java/com/informatika/bondoman/di/NetworkModule.kt
@@ -3,7 +3,6 @@ package com.informatika.bondoman.di
 import com.informatika.bondoman.BuildConfig
 import com.informatika.bondoman.model.remote.AuthService
 import com.squareup.moshi.Moshi
-import com.squareup.moshi.kotlin.reflect.KotlinJsonAdapterFactory
 import okhttp3.Interceptor
 import okhttp3.OkHttpClient
 import okhttp3.logging.HttpLoggingInterceptor
@@ -31,15 +30,8 @@ val networkModule = module {
             .build()
     }
 
-    // Dependency: Moshi
-    single<Moshi> {
-        Moshi.Builder()
-            .add(KotlinJsonAdapterFactory())
-            .build()
-    }
-
     // Dependency: Retrofit
-    single {
+    single<Retrofit> {
         Retrofit.Builder()
             .baseUrl(BuildConfig.BASE_URL)
             .client(get())
@@ -48,8 +40,5 @@ val networkModule = module {
     }
 
     // Dependency: ApiService
-    single {
-        val retrofit: Retrofit = get()
-        retrofit.create(AuthService::class.java)
-    }
+    single<AuthService> {get<Retrofit>().create(AuthService::class.java)}
 }
\ No newline at end of file
diff --git a/app/src/main/java/com/informatika/bondoman/di/RepositoryModule.kt b/app/src/main/java/com/informatika/bondoman/di/RepositoryModule.kt
new file mode 100644
index 0000000000000000000000000000000000000000..1b6c40cacc04c03fcbe65b87603aac5ad06c51d2
--- /dev/null
+++ b/app/src/main/java/com/informatika/bondoman/di/RepositoryModule.kt
@@ -0,0 +1,26 @@
+package com.informatika.bondoman.di
+
+import com.informatika.bondoman.model.repository.login.LoginRepository
+import com.informatika.bondoman.model.repository.login.LoginRepositoryImpl
+import com.informatika.bondoman.model.repository.token.TokenRepository
+import com.informatika.bondoman.model.repository.token.TokenRepositoryImpl
+import com.informatika.bondoman.model.repository.transaction.TransactionRepository
+import com.informatika.bondoman.model.repository.transaction.TransactionRepositoryImpl
+import org.koin.dsl.module
+
+val repositoryModule = module {
+    // Dependency: LoginRepository
+    single<LoginRepository> {
+        LoginRepositoryImpl(get())
+    }
+
+    single<TokenRepository> {
+        TokenRepositoryImpl(get())
+    }
+
+    // Dependency: TransactionRepository
+    single<TransactionRepository> {
+        TransactionRepositoryImpl(get())
+    }
+
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/informatika/bondoman/di/ViewModelModule.kt b/app/src/main/java/com/informatika/bondoman/di/ViewModelModule.kt
index 4dd6ff5794bea66d83e644d8b35c88e59dddb6b7..acd0370c4c45a950fef492185177cb74c895f381 100644
--- a/app/src/main/java/com/informatika/bondoman/di/ViewModelModule.kt
+++ b/app/src/main/java/com/informatika/bondoman/di/ViewModelModule.kt
@@ -1,17 +1,26 @@
 package com.informatika.bondoman.di
 
-import com.informatika.bondoman.model.repository.LoginRepository
+import com.informatika.bondoman.prefdatastore.JWTManager
+import com.informatika.bondoman.prefdatastore.JWTManagerImpl
+import com.informatika.bondoman.viewmodel.JWTViewModel
 import org.koin.androidx.viewmodel.dsl.viewModel
 import com.informatika.bondoman.viewmodel.login.LoginViewModel
 import com.informatika.bondoman.viewmodel.transaction.CreateTransactionViewModel
 import com.informatika.bondoman.viewmodel.transaction.DetailTransactionViewModel
-import com.informatika.bondoman.viewmodel.transaction.UpdateTransactionViewModel
 import com.informatika.bondoman.viewmodel.transaction.ListTransactionViewModel
+import com.informatika.bondoman.viewmodel.transaction.UpdateTransactionViewModel
+import org.koin.android.ext.koin.androidContext
+import org.koin.androidx.viewmodel.dsl.viewModelOf
 import org.koin.dsl.module
 
 val viewModelModule = module {
-    // Dependency: LoginViewModel
+    // Dependency: JWTViewModel
     viewModel {
+        JWTViewModel(JWTManagerImpl(androidContext()), get())
+    }
+
+    // Dependency: LoginViewModel
+    viewModel<LoginViewModel> {
         LoginViewModel(get())
     }
 
@@ -22,12 +31,12 @@ val viewModelModule = module {
 
     // Dependency: DetailTransactionViewModel
     viewModel {
-        parameters -> DetailTransactionViewModel(get(), transaction = parameters.get())
+        parameters -> DetailTransactionViewModel(get(), _id = parameters.get())
     }
 
     // Dependency: UpdateTransactionViewModel
     viewModel {
-        parameters -> UpdateTransactionViewModel(get(), transaction = parameters.get())
+        parameters -> UpdateTransactionViewModel(get(), _id = parameters.get())
     }
 
     // Dependency: ListTransactionViewModel
@@ -35,7 +44,4 @@ val viewModelModule = module {
         ListTransactionViewModel(get())
     }
 
-    single {
-        LoginRepository(get())
-    }
 }
\ No newline at end of file
diff --git a/app/src/main/java/com/informatika/bondoman/model/local/AppDB.kt b/app/src/main/java/com/informatika/bondoman/model/local/AppDatabase.kt
similarity index 65%
rename from app/src/main/java/com/informatika/bondoman/model/local/AppDB.kt
rename to app/src/main/java/com/informatika/bondoman/model/local/AppDatabase.kt
index cef0784beba5dab9fa801ee55e98b2bde5cc0c40..bfd5facac987b653a1bca76ed644bc7f268dfd0f 100644
--- a/app/src/main/java/com/informatika/bondoman/model/local/AppDB.kt
+++ b/app/src/main/java/com/informatika/bondoman/model/local/AppDatabase.kt
@@ -3,9 +3,9 @@ package com.informatika.bondoman.model.local
 import androidx.room.Database
 import androidx.room.RoomDatabase
 import com.informatika.bondoman.model.local.dao.TransactionDao
-import com.informatika.bondoman.model.local.entity.Transaction
+import com.informatika.bondoman.model.local.entity.transaction.Transaction
 
-@Database(entities = [Transaction::class], version = DBConstants.mVersion)
-abstract class AppDB : RoomDatabase() {
+@Database(entities = [Transaction::class], version = DBConstants.mVersion, exportSchema = false)
+abstract class AppDatabase : RoomDatabase() {
     abstract fun transactionDao(): TransactionDao
 }
\ No newline at end of file
diff --git a/app/src/main/java/com/informatika/bondoman/model/local/dao/TransactionDao.kt b/app/src/main/java/com/informatika/bondoman/model/local/dao/TransactionDao.kt
index 6def362937b5d3e1c58a4558cada5ba71313ffe2..88a853a5599d66d9da2271c130868878441d4167 100644
--- a/app/src/main/java/com/informatika/bondoman/model/local/dao/TransactionDao.kt
+++ b/app/src/main/java/com/informatika/bondoman/model/local/dao/TransactionDao.kt
@@ -9,22 +9,22 @@ import com.informatika.bondoman.model.local.entity.transaction.Transaction
 
 @Dao
 interface TransactionDao {
-    @Query("SELECT * FROM " + DBConstants.mTableTransaction + " WHERE _id = :id")
+    @Query("SELECT * FROM `" + DBConstants.mTableTransaction + "` WHERE _id = :id")
     suspend fun get(id: Int): Transaction
 
-    @Query("SELECT * FROM " + DBConstants.mTableTransaction + " ORDER BY createdAt DESC")
+    @Query("SELECT * FROM `" + DBConstants.mTableTransaction + "` ORDER BY createdAt DESC")
     suspend fun getAll(): List<Transaction>
 
-    @Query("INSERT INTO " + DBConstants.mTableTransaction + " (title, category, amount, location) VALUES(:title, :category, :amount, :location)")
+    @Query("INSERT INTO `" + DBConstants.mTableTransaction + "` (title, category, amount, location) VALUES(:title, :category, :amount, :location)")
     suspend fun insert(title: String, category: Category, amount: Int, location: String)
 
-    @Query("INSERT INTO " + DBConstants.mTableTransaction + " (title, category, amount) VALUES(:title, :category, :amount)")
+    @Query("INSERT INTO `" + DBConstants.mTableTransaction + "` (title, category, amount) VALUES(:title, :category, :amount)")
     suspend fun insert(title: String, category: Category, amount: Int)
 
-    @Query("UPDATE " + DBConstants.mTableTransaction + " SET title = :title, amount = :amount, location = :location")
+    @Query("UPDATE `" + DBConstants.mTableTransaction + "` SET title = :title, amount = :amount, location = :location")
     suspend fun update(title: String, amount: Int, location: String)
 
-    @Query("UPDATE " + DBConstants.mTableTransaction + " SET title = :title, amount = :amount")
+    @Query("UPDATE `" + DBConstants.mTableTransaction + "` SET title = :title, amount = :amount")
     suspend fun update(title: String, amount: Int)
 
     @Delete
diff --git a/app/src/main/java/com/informatika/bondoman/model/repository/login/LoginRepository.kt b/app/src/main/java/com/informatika/bondoman/model/repository/login/LoginRepository.kt
new file mode 100644
index 0000000000000000000000000000000000000000..a188e80ffc347fda4ec38ce9c1845a27dbf81477
--- /dev/null
+++ b/app/src/main/java/com/informatika/bondoman/model/repository/login/LoginRepository.kt
@@ -0,0 +1,8 @@
+package com.informatika.bondoman.model.repository.login
+
+import com.informatika.bondoman.model.Resource
+import com.informatika.bondoman.model.remote.AuthService
+
+interface LoginRepository {
+    suspend fun login(username: String, password: String): Resource<String>
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/informatika/bondoman/model/repository/LoginRepository.kt b/app/src/main/java/com/informatika/bondoman/model/repository/login/LoginRepositoryImpl.kt
similarity index 79%
rename from app/src/main/java/com/informatika/bondoman/model/repository/LoginRepository.kt
rename to app/src/main/java/com/informatika/bondoman/model/repository/login/LoginRepositoryImpl.kt
index eea2c0c7c79c05adde969f83fc7ee4cef5ccd068..d732a5749c8fd1b6cc8f082c92bd423a57c3eb3a 100644
--- a/app/src/main/java/com/informatika/bondoman/model/repository/LoginRepository.kt
+++ b/app/src/main/java/com/informatika/bondoman/model/repository/login/LoginRepositoryImpl.kt
@@ -1,14 +1,13 @@
-package com.informatika.bondoman.model.repository
+package com.informatika.bondoman.model.repository.login
 
 import com.informatika.bondoman.model.remote.request.LoginRequest
-import com.informatika.bondoman.network.ApiClient
 import com.informatika.bondoman.model.Resource
 import com.informatika.bondoman.model.remote.AuthService
 import retrofit2.awaitResponse
 import java.io.IOException
 
-class LoginRepository constructor(private val authService: AuthService) {
-    suspend fun login(username: String, password: String): Resource<String> {
+class LoginRepositoryImpl constructor(private var authService: AuthService) : LoginRepository {
+    override suspend fun login(username: String, password: String): Resource<String> {
         try {
             val call = authService.login(LoginRequest(username, password))
             val response = call.awaitResponse()
diff --git a/app/src/main/java/com/informatika/bondoman/model/repository/token/TokenRepository.kt b/app/src/main/java/com/informatika/bondoman/model/repository/token/TokenRepository.kt
new file mode 100644
index 0000000000000000000000000000000000000000..201ac8bd646643ba7403cd5d28204157cbb892cc
--- /dev/null
+++ b/app/src/main/java/com/informatika/bondoman/model/repository/token/TokenRepository.kt
@@ -0,0 +1,7 @@
+package com.informatika.bondoman.model.repository.token
+
+import com.informatika.bondoman.model.Resource
+
+interface TokenRepository {
+    suspend fun token(token: String): Resource<Boolean>
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/informatika/bondoman/model/repository/TokenRepository.kt b/app/src/main/java/com/informatika/bondoman/model/repository/token/TokenRepositoryImpl.kt
similarity index 68%
rename from app/src/main/java/com/informatika/bondoman/model/repository/TokenRepository.kt
rename to app/src/main/java/com/informatika/bondoman/model/repository/token/TokenRepositoryImpl.kt
index 19492589e7220a6e119239b547ef8ab51144adae..babff4e8fb5d9698209366e7fce19227ae0498b7 100644
--- a/app/src/main/java/com/informatika/bondoman/model/repository/TokenRepository.kt
+++ b/app/src/main/java/com/informatika/bondoman/model/repository/token/TokenRepositoryImpl.kt
@@ -1,15 +1,15 @@
-package com.informatika.bondoman.model.repository
+package com.informatika.bondoman.model.repository.token
 
-import android.util.Log
 import com.informatika.bondoman.network.ApiClient
 import com.informatika.bondoman.model.Resource
+import com.informatika.bondoman.model.remote.AuthService
 import retrofit2.awaitResponse
 import timber.log.Timber
 
-class TokenRepository {
-    suspend fun token(token: String): Resource<Boolean> {
+class TokenRepositoryImpl(private var authService: AuthService) : TokenRepository {
+    override suspend fun token(token: String): Resource<Boolean> {
         try {
-            val call = ApiClient.authService.token("Bearer $token")
+            val call = authService.token("Bearer $token")
             val response = call.awaitResponse()
 
             Timber.tag("status").d(response.code().toString())
diff --git a/app/src/main/java/com/informatika/bondoman/model/repository/transaction/TransactionRepository.kt b/app/src/main/java/com/informatika/bondoman/model/repository/transaction/TransactionRepository.kt
new file mode 100644
index 0000000000000000000000000000000000000000..5c2608a2c34675d7474a18ba0e9c4312631875fd
--- /dev/null
+++ b/app/src/main/java/com/informatika/bondoman/model/repository/transaction/TransactionRepository.kt
@@ -0,0 +1,27 @@
+package com.informatika.bondoman.model.repository.transaction
+
+import androidx.lifecycle.LiveData
+import androidx.lifecycle.MutableLiveData
+import com.informatika.bondoman.model.Resource
+import com.informatika.bondoman.model.local.entity.transaction.Category
+import com.informatika.bondoman.model.local.entity.transaction.Transaction
+
+interface TransactionRepository {
+    val _listTransactionLiveData: MutableLiveData<Resource<List<Transaction>>>
+    val listTransactionLiveData: LiveData<Resource<List<Transaction>>>
+        get() = listTransactionLiveData
+
+    val _transactionLiveData: MutableLiveData<Resource<Transaction>>
+    val transactionLiveData: LiveData<Resource<Transaction>>
+        get() = transactionLiveData
+
+    suspend fun getTransaction(id: Int)
+    suspend fun getAllTransaction()
+    suspend fun insertTransaction(title: String, category: Category, amount: Int, location: String)
+    suspend fun insertTransaction(title: String, category: Category, amount: Int)
+    suspend fun updateTransaction(title: String, amount: Int, location: String)
+    suspend fun updateTransaction(title: String, amount: Int)
+    suspend fun deleteTransaction(transaction: Transaction)
+    suspend fun refreshTransaction()
+
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/informatika/bondoman/model/repository/TransactionRepository.kt b/app/src/main/java/com/informatika/bondoman/model/repository/transaction/TransactionRepositoryImpl.kt
similarity index 55%
rename from app/src/main/java/com/informatika/bondoman/model/repository/TransactionRepository.kt
rename to app/src/main/java/com/informatika/bondoman/model/repository/transaction/TransactionRepositoryImpl.kt
index dc4c07462c52d8c5e24c306ae5e183cd25392f23..66f4a7d40755d43411fc8ea8a16ba6967c9241f3 100644
--- a/app/src/main/java/com/informatika/bondoman/model/repository/TransactionRepository.kt
+++ b/app/src/main/java/com/informatika/bondoman/model/repository/transaction/TransactionRepositoryImpl.kt
@@ -1,4 +1,4 @@
-package com.informatika.bondoman.model.repository
+package com.informatika.bondoman.model.repository.transaction
 
 import androidx.lifecycle.LiveData
 import androidx.lifecycle.MutableLiveData
@@ -7,14 +7,20 @@ import com.informatika.bondoman.model.local.dao.TransactionDao
 import com.informatika.bondoman.model.local.entity.transaction.Category
 import com.informatika.bondoman.model.local.entity.transaction.Transaction
 
-class TransactionRepository(private var transactionDao: TransactionDao) {
-    private val _listTransactionLiveData = MutableLiveData<Resource<List<Transaction>>>()
-    private val listTransactionLiveData : LiveData<Resource<List<Transaction>>> = _listTransactionLiveData
+class TransactionRepositoryImpl(private var transactionDao: TransactionDao) : TransactionRepository {
+    override var _listTransactionLiveData = MutableLiveData<Resource<List<Transaction>>>()
+        private set
+    override var listTransactionLiveData : LiveData<Resource<List<Transaction>>> = _listTransactionLiveData
+        private set
+        get() = _listTransactionLiveData
 
-    private val _transactionLiveData = MutableLiveData<Resource<Transaction>>()
-    private val transactionLiveData : LiveData<Resource<Transaction>> = _transactionLiveData
+    override var _transactionLiveData = MutableLiveData<Resource<Transaction>>()
+        private set
+    override var transactionLiveData : LiveData<Resource<Transaction>> = _transactionLiveData
+        private set
+        get() = _transactionLiveData
 
-    suspend fun getTransaction(id: Int) {
+    override suspend fun getTransaction(id: Int) {
         _transactionLiveData.postValue(Resource.Loading())
         try {
             val transaction = transactionDao.get(id)
@@ -24,7 +30,7 @@ class TransactionRepository(private var transactionDao: TransactionDao) {
         }
     }
 
-    suspend fun getAllTransaction() {
+    override suspend fun getAllTransaction() {
         _listTransactionLiveData.postValue(Resource.Loading())
         try {
             val transactionList = transactionDao.getAll()
@@ -34,27 +40,27 @@ class TransactionRepository(private var transactionDao: TransactionDao) {
         }
     }
 
-    suspend fun insertTransaction(title: String, category: Category, amount: Int, location: String) {
+    override suspend fun insertTransaction(title: String, category: Category, amount: Int, location: String) {
         transactionDao.insert(title, category, amount, location)
     }
 
-    suspend fun insertTransaction(title: String, category: Category, amount: Int) {
+    override suspend fun insertTransaction(title: String, category: Category, amount: Int) {
         transactionDao.insert(title, category, amount)
     }
 
-    suspend fun updateTransaction(title: String, amount: Int, location: String) {
+    override suspend fun updateTransaction(title: String, amount: Int, location: String) {
         transactionDao.update(title, amount, location)
     }
 
-    suspend fun updateTransaction(title: String, amount: Int) {
+    override suspend fun updateTransaction(title: String, amount: Int) {
         transactionDao.update(title, amount)
     }
 
-    suspend fun deleteTransaction(transaction: Transaction) {
+    override suspend fun deleteTransaction(transaction: Transaction) {
         transactionDao.delete(transaction)
     }
 
-    suspend fun refreshTransaction() {
+    override suspend fun refreshTransaction() {
         _listTransactionLiveData.postValue(Resource.Loading())
         try {
             val transactionList = transactionDao.getAll()
@@ -63,8 +69,4 @@ class TransactionRepository(private var transactionDao: TransactionDao) {
             _listTransactionLiveData.postValue(Resource.Error(e))
         }
     }
-
-    fun getListTransactionLiveData() = listTransactionLiveData
-
-    fun getTransactionLiveData() = transactionLiveData
 }
\ No newline at end of file
diff --git a/app/src/main/java/com/informatika/bondoman/prefdatastore/JWTManager.kt b/app/src/main/java/com/informatika/bondoman/prefdatastore/JWTManager.kt
index 1e232f6c42159a29a5da184fef6c29f6f0bd810e..e7f9a281c36388738505699a060af2cc5a48f078 100644
--- a/app/src/main/java/com/informatika/bondoman/prefdatastore/JWTManager.kt
+++ b/app/src/main/java/com/informatika/bondoman/prefdatastore/JWTManager.kt
@@ -1,65 +1,13 @@
 package com.informatika.bondoman.prefdatastore
 
-import android.content.Context
-import androidx.datastore.core.DataStore
-import androidx.datastore.preferences.core.Preferences
-import androidx.datastore.preferences.core.edit
-import androidx.datastore.preferences.core.stringPreferencesKey
-import androidx.datastore.preferences.preferencesDataStore
-import com.informatika.bondoman.model.Resource
-import com.informatika.bondoman.model.repository.TokenRepository
 import kotlinx.coroutines.flow.Flow
-import kotlinx.coroutines.flow.firstOrNull
-import kotlinx.coroutines.flow.map
 
-const val KEY_TOKEN = "jwt_token"
-val Context.dataStore: DataStore<Preferences> by preferencesDataStore(name = KEY_TOKEN)
+interface JWTManager {
+    fun isAuthenticated(): Flow<Boolean>
 
-class JWTManager(private val context: Context) {
-    private val tokenRepository = TokenRepository()
+    suspend fun getToken(): String
 
-    // returns a flow of is authenticated state
-    fun isAuthenticated(): Flow<Boolean> {
-        // flow of token existence from dataStore
-        return context.dataStore.data.map {
-            it.contains(JWT_TOKEN)
-        }
-    }
+    suspend fun saveToken(token: String)
 
-    suspend fun getToken(): String {
-        return context.dataStore.data
-            .map { it[JWT_TOKEN] } // get a flow of token from dataStore
-            .firstOrNull() // transform flow to suspend
-            ?: throw IllegalArgumentException("no token stored")
-    }
-
-    // store new token after sign in or token refresh
-    suspend fun saveToken(token: String) {
-        context.dataStore.edit {
-            it[JWT_TOKEN] = token
-        }
-    }
-
-    suspend fun isExpired(): Boolean {
-        return when (val result = tokenRepository.token(getToken())) {
-            is Resource.Success -> {
-                !result.data
-            }
-
-            else -> {
-                true
-            }
-        }
-    }
-
-    // to call when user logs out or when refreshing the token has failed
-    suspend fun onLogout() {
-        context.dataStore.edit {
-            it.remove(JWT_TOKEN)
-        }
-    }
-
-    companion object {
-        val JWT_TOKEN = stringPreferencesKey(KEY_TOKEN)
-    }
+    suspend fun onLogout()
 }
\ No newline at end of file
diff --git a/app/src/main/java/com/informatika/bondoman/prefdatastore/JWTManagerImpl.kt b/app/src/main/java/com/informatika/bondoman/prefdatastore/JWTManagerImpl.kt
new file mode 100644
index 0000000000000000000000000000000000000000..c7a5016406659601ff929240a4223f9b72349b37
--- /dev/null
+++ b/app/src/main/java/com/informatika/bondoman/prefdatastore/JWTManagerImpl.kt
@@ -0,0 +1,50 @@
+package com.informatika.bondoman.prefdatastore
+
+import android.content.Context
+import androidx.datastore.core.DataStore
+import androidx.datastore.preferences.core.Preferences
+import androidx.datastore.preferences.core.edit
+import androidx.datastore.preferences.core.stringPreferencesKey
+import androidx.datastore.preferences.preferencesDataStore
+import kotlinx.coroutines.flow.Flow
+import kotlinx.coroutines.flow.firstOrNull
+import kotlinx.coroutines.flow.map
+
+const val KEY_TOKEN = "jwt_token"
+val Context.dataStore: DataStore<Preferences> by preferencesDataStore(name = KEY_TOKEN)
+
+class JWTManagerImpl(private val context: Context) : JWTManager {
+
+    // returns a flow of is authenticated state
+    override fun isAuthenticated(): Flow<Boolean> {
+        // flow of token existence from dataStore
+        return context.dataStore.data.map {
+            it.contains(JWT_TOKEN)
+        }
+    }
+
+    override suspend fun getToken(): String {
+        return context.dataStore.data
+            .map { it[JWT_TOKEN] } // get a flow of token from dataStore
+            .firstOrNull() // transform flow to suspend
+            ?: throw IllegalArgumentException("no token stored")
+    }
+
+    // store new token after sign in or token refresh
+    override suspend fun saveToken(token: String) {
+        context.dataStore.edit {
+            it[JWT_TOKEN] = token
+        }
+    }
+
+    // to call when user logs out or when refreshing the token has failed
+    override suspend fun onLogout() {
+        context.dataStore.edit {
+            it.remove(JWT_TOKEN)
+        }
+    }
+
+    companion object {
+        val JWT_TOKEN = stringPreferencesKey(KEY_TOKEN)
+    }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/informatika/bondoman/view/activity/LoginActivity.kt b/app/src/main/java/com/informatika/bondoman/view/activity/LoginActivity.kt
index 38fbe0422733f516cde3f7604a51ec2824764156..dfb2b29be7f71c3dd0010d4e4f1dc1a36a7d4b08 100644
--- a/app/src/main/java/com/informatika/bondoman/view/activity/LoginActivity.kt
+++ b/app/src/main/java/com/informatika/bondoman/view/activity/LoginActivity.kt
@@ -12,23 +12,33 @@ import android.view.View
 import android.view.inputmethod.EditorInfo
 import android.widget.EditText
 import android.widget.Toast
-import androidx.activity.viewModels
 import com.informatika.bondoman.MainActivity
 import com.informatika.bondoman.databinding.ActivityLoginBinding
 import com.informatika.bondoman.R
 import com.informatika.bondoman.prefdatastore.JWTManager
+import com.informatika.bondoman.prefdatastore.JWTManagerImpl
+import com.informatika.bondoman.viewmodel.JWTViewModel
 import com.informatika.bondoman.viewmodel.login.LoginViewModel
 import kotlinx.coroutines.runBlocking
+import org.koin.android.ext.koin.androidContext
+import org.koin.androidx.viewmodel.ext.android.viewModel
+import org.koin.core.parameter.parametersOf
+import org.koin.core.context.startKoin
+import timber.log.Timber
 
 class LoginActivity : AppCompatActivity() {
-    private val loginViewModel: LoginViewModel by viewModels<LoginViewModel>()
+    private val loginViewModel: LoginViewModel by viewModel()
 
     private lateinit var binding: ActivityLoginBinding
-    private lateinit var jwtManager: JWTManager
+    private val jwtViewModel: JWTViewModel by viewModel()
 
     override fun onCreate(savedInstanceState: Bundle?) {
         super.onCreate(savedInstanceState)
 
+//        initTimber()
+//        initKoin()
+        // koin set android context
+
         binding = ActivityLoginBinding.inflate(layoutInflater)
         setContentView(binding.root)
 
@@ -37,7 +47,6 @@ class LoginActivity : AppCompatActivity() {
         val login = binding.login
         val loading = binding.loading
 
-        jwtManager = JWTManager(applicationContext)
 
         loginViewModel.loginFormState.observe(this@LoginActivity, Observer {
             val loginState = it ?: return@Observer
@@ -59,9 +68,8 @@ class LoginActivity : AppCompatActivity() {
             } else {
                 if (loginResult.jwtToken != null) {
                     runBlocking {
-                        jwtManager.saveToken(loginResult.jwtToken)
+                        jwtViewModel.jwtManager.saveToken(loginResult.jwtToken)
                     }
-
                     updateUiWithUser()
                     val intent = Intent(this@LoginActivity, MainActivity::class.java)
                     startActivity(intent)
@@ -129,4 +137,5 @@ class LoginActivity : AppCompatActivity() {
             override fun onTextChanged(s: CharSequence, start: Int, before: Int, count: Int) {}
         })
     }
+
 }
\ No newline at end of file
diff --git a/app/src/main/java/com/informatika/bondoman/view/activity/MainEmptyActivity.kt b/app/src/main/java/com/informatika/bondoman/view/activity/MainEmptyActivity.kt
index 9e732be57ea30f1a21c1a8f3e4db9f76caa570df..3c7f5b61c20b7c7c69a887fc09c300ef0dcec212 100644
--- a/app/src/main/java/com/informatika/bondoman/view/activity/MainEmptyActivity.kt
+++ b/app/src/main/java/com/informatika/bondoman/view/activity/MainEmptyActivity.kt
@@ -10,17 +10,21 @@ import androidx.lifecycle.lifecycleScope
 import com.informatika.bondoman.BuildConfig
 import com.informatika.bondoman.MainActivity
 import com.informatika.bondoman.databinding.ActivityMainEmptyBinding
+import com.informatika.bondoman.di.applicationModule
 import com.informatika.bondoman.di.databaseModule
 import com.informatika.bondoman.di.networkModule
+import com.informatika.bondoman.di.repositoryModule
 import com.informatika.bondoman.di.viewModelModule
 import com.informatika.bondoman.prefdatastore.JWTManager
+import com.informatika.bondoman.viewmodel.JWTViewModel
 import kotlinx.coroutines.launch
 import org.koin.android.ext.koin.androidContext
+import org.koin.androidx.viewmodel.ext.android.viewModel
 import org.koin.core.context.startKoin
 import timber.log.Timber
 
 class MainEmptyActivity : AppCompatActivity() {
-    private lateinit var jwtManager: JWTManager
+    private val jwtViewModel: JWTViewModel by viewModel()
     private lateinit var binding: ActivityMainEmptyBinding
     override fun onCreate(savedInstanceState: Bundle?) {
         super.onCreate(savedInstanceState)
@@ -38,30 +42,36 @@ class MainEmptyActivity : AppCompatActivity() {
         installSplashScreen()
 
         enableEdgeToEdge()
+    }
 
-        jwtManager = JWTManager(applicationContext)
-        lifecycleScope.launch {
-            jwtManager.isAuthenticated().collect {
-                if (it) {
-                    val intent = Intent(this@MainEmptyActivity, MainActivity::class.java)
-                    startActivity(intent)
-                    finish()
+    override fun onStart() {
+        super.onStart()
+        if (BuildConfig.DEBUG) {
+            Timber.d("onStart")
+        }
 
-                } else {
-                    val intent = Intent(this@MainEmptyActivity, LoginActivity::class.java)
-                    startActivity(intent)
-                    finish()
-                }
+        lifecycleScope.launch {
+            if (jwtViewModel.isExpired()) {
+                val intent = Intent(this@MainEmptyActivity, LoginActivity::class.java)
+                startActivity(intent)
+                finish()
+            } else {
+                val intent = Intent(this@MainEmptyActivity, MainActivity::class.java)
+                startActivity(intent)
+                finish()
             }
         }
     }
 
     private fun initKoin() {
         startKoin {
+            androidContext(this@MainEmptyActivity)
             modules(
                 listOf(
+                    applicationModule,
                     databaseModule,
                     networkModule,
+                    repositoryModule,
                     viewModelModule
                 )
             )
diff --git a/app/src/main/java/com/informatika/bondoman/view/fragment/TransactionFragment.kt b/app/src/main/java/com/informatika/bondoman/view/fragment/TransactionFragment.kt
index 9cfd7105084e731ac1bc1ef76015662c707d7bbe..deb050402b8843d9b32ee8db37cdc66fc19bc327 100644
--- a/app/src/main/java/com/informatika/bondoman/view/fragment/TransactionFragment.kt
+++ b/app/src/main/java/com/informatika/bondoman/view/fragment/TransactionFragment.kt
@@ -5,18 +5,26 @@ import androidx.fragment.app.Fragment
 import android.view.LayoutInflater
 import android.view.View
 import android.view.ViewGroup
-import androidx.fragment.app.viewModels
+import org.koin.androidx.viewmodel.ext.android.viewModel
 import com.informatika.bondoman.R
+import com.informatika.bondoman.viewmodel.transaction.CreateTransactionViewModel
+import com.informatika.bondoman.viewmodel.transaction.DetailTransactionViewModel
 import com.informatika.bondoman.viewmodel.transaction.ListTransactionViewModel
+import com.informatika.bondoman.viewmodel.transaction.UpdateTransactionViewModel
+import org.koin.core.parameter.parametersOf
 
 class TransactionFragment : Fragment() {
+    val _id: Int = 0
+    // TODO: delete unused viewModels just dummy
+    private val listTransactionViewModel: ListTransactionViewModel by viewModel()
+    private val detailTransactionViewModel: DetailTransactionViewModel by viewModel { parametersOf(_id) }
+    private val updateTransactionViewModel: UpdateTransactionViewModel by viewModel { parametersOf(_id) }
+    private val createTransactionViewModel: CreateTransactionViewModel by viewModel()
 
     companion object {
         fun newInstance() = TransactionFragment()
     }
 
-    private val viewModel: ListTransactionViewModel by viewModels()
-
     override fun onCreateView(
         inflater: LayoutInflater, container: ViewGroup?,
         savedInstanceState: Bundle?
diff --git a/app/src/main/java/com/informatika/bondoman/viewmodel/JWTViewModel.kt b/app/src/main/java/com/informatika/bondoman/viewmodel/JWTViewModel.kt
new file mode 100644
index 0000000000000000000000000000000000000000..71fcb3440f7df81f8bccfb1254cf9a2a7eee715c
--- /dev/null
+++ b/app/src/main/java/com/informatika/bondoman/viewmodel/JWTViewModel.kt
@@ -0,0 +1,28 @@
+package com.informatika.bondoman.viewmodel
+
+import androidx.lifecycle.ViewModel
+import androidx.lifecycle.viewModelScope
+import com.informatika.bondoman.model.Resource
+import com.informatika.bondoman.model.repository.token.TokenRepository
+import com.informatika.bondoman.prefdatastore.JWTManager
+import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.launch
+import timber.log.Timber
+
+class JWTViewModel(var jwtManager: JWTManager, private var tokenRepository: TokenRepository): ViewModel() {
+    suspend fun isExpired(): Boolean {
+        var isExpired = true
+        try {
+            val result = tokenRepository.token(jwtManager.getToken())
+            if (result is Resource.Success) {
+                isExpired = false
+            } else {
+                jwtManager.onLogout()
+            }
+        } catch (e: Exception) {
+            Timber.tag("JWT").d("No token found")
+        }
+        return isExpired
+    }
+
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/informatika/bondoman/viewmodel/login/LoginViewModel.kt b/app/src/main/java/com/informatika/bondoman/viewmodel/login/LoginViewModel.kt
index 355b4847a3861d6c1ce8de2e0e5b2a41f9c339a8..0b3bf85d3d61bebf592008addde2b6caf8b49579 100644
--- a/app/src/main/java/com/informatika/bondoman/viewmodel/login/LoginViewModel.kt
+++ b/app/src/main/java/com/informatika/bondoman/viewmodel/login/LoginViewModel.kt
@@ -4,12 +4,12 @@ import androidx.lifecycle.LiveData
 import androidx.lifecycle.MutableLiveData
 import androidx.lifecycle.ViewModel
 import android.util.Patterns
-import androidx.lifecycle.ViewModelProvider
 import androidx.lifecycle.viewModelScope
-import com.informatika.bondoman.model.repository.LoginRepository
+import com.informatika.bondoman.model.repository.login.LoginRepositoryImpl
 import com.informatika.bondoman.model.Resource
 
 import com.informatika.bondoman.R
+import com.informatika.bondoman.model.repository.login.LoginRepository
 import kotlinx.coroutines.Dispatchers
 import kotlinx.coroutines.launch
 
diff --git a/app/src/main/java/com/informatika/bondoman/viewmodel/transaction/CreateTransactionViewModel.kt b/app/src/main/java/com/informatika/bondoman/viewmodel/transaction/CreateTransactionViewModel.kt
index e8296e5b8eb9700e74aed1007de5f22a156af15a..6453553cc45c3060682cbfd77ae3bab6cc887cde 100644
--- a/app/src/main/java/com/informatika/bondoman/viewmodel/transaction/CreateTransactionViewModel.kt
+++ b/app/src/main/java/com/informatika/bondoman/viewmodel/transaction/CreateTransactionViewModel.kt
@@ -6,7 +6,7 @@ import androidx.lifecycle.ViewModel
 import androidx.lifecycle.viewModelScope
 import com.informatika.bondoman.R
 import com.informatika.bondoman.model.local.entity.transaction.Category
-import com.informatika.bondoman.model.repository.TransactionRepository
+import com.informatika.bondoman.model.repository.transaction.TransactionRepository
 import com.informatika.bondoman.viewmodel.transaction.helper.TransactionFormState
 import kotlinx.coroutines.launch
 
diff --git a/app/src/main/java/com/informatika/bondoman/viewmodel/transaction/DetailTransactionViewModel.kt b/app/src/main/java/com/informatika/bondoman/viewmodel/transaction/DetailTransactionViewModel.kt
index de71945aa0b0007158e459e7cf28d9d9c683e0f7..eda6c439fea853bbed8d427f13c7c58a9d9916de 100644
--- a/app/src/main/java/com/informatika/bondoman/viewmodel/transaction/DetailTransactionViewModel.kt
+++ b/app/src/main/java/com/informatika/bondoman/viewmodel/transaction/DetailTransactionViewModel.kt
@@ -5,24 +5,24 @@ import androidx.lifecycle.ViewModel
 import androidx.lifecycle.viewModelScope
 import com.informatika.bondoman.model.Resource
 import com.informatika.bondoman.model.local.entity.transaction.Transaction
-import com.informatika.bondoman.model.repository.TransactionRepository
+import com.informatika.bondoman.model.repository.transaction.TransactionRepository
 import kotlinx.coroutines.launch
 
-class DetailTransactionViewModel(private var transactionRepository: TransactionRepository, transaction: Transaction) : ViewModel() {
+class DetailTransactionViewModel(private var transactionRepository: TransactionRepository, _id: Int) : ViewModel() {
     val transactionLiveData = MutableLiveData<Resource<Transaction>>()
     private val observer = androidx.lifecycle.Observer<Resource<Transaction>> {
         transactionLiveData.postValue(it)
     }
 
     init {
-        transactionRepository.getTransactionLiveData().observeForever(observer)
+        transactionRepository.transactionLiveData.observeForever(observer)
         viewModelScope.launch {
-            transactionRepository.getTransaction(transaction._id)
+            transactionRepository.getTransaction(_id)
         }
     }
 
     override fun onCleared() {
         super.onCleared()
-        transactionRepository.getTransactionLiveData().removeObserver(observer)
+        transactionRepository.transactionLiveData.removeObserver(observer)
     }
 }
\ No newline at end of file
diff --git a/app/src/main/java/com/informatika/bondoman/viewmodel/transaction/ListTransactionViewModel.kt b/app/src/main/java/com/informatika/bondoman/viewmodel/transaction/ListTransactionViewModel.kt
index 279d0e1e07c4335e8f6095583107863e0b987579..99501a6043c50bdaaf083b27611b3f83ad4911cc 100644
--- a/app/src/main/java/com/informatika/bondoman/viewmodel/transaction/ListTransactionViewModel.kt
+++ b/app/src/main/java/com/informatika/bondoman/viewmodel/transaction/ListTransactionViewModel.kt
@@ -5,7 +5,7 @@ import androidx.lifecycle.ViewModel
 import androidx.lifecycle.viewModelScope
 import com.informatika.bondoman.model.Resource
 import com.informatika.bondoman.model.local.entity.transaction.Transaction
-import com.informatika.bondoman.model.repository.TransactionRepository
+import com.informatika.bondoman.model.repository.transaction.TransactionRepository
 import kotlinx.coroutines.launch
 
 class ListTransactionViewModel(private var transactionRepository: TransactionRepository) : ViewModel() {
@@ -15,7 +15,7 @@ class ListTransactionViewModel(private var transactionRepository: TransactionRep
     }
 
     init {
-        transactionRepository.getListTransactionLiveData().observeForever(observer)
+        transactionRepository.listTransactionLiveData.observeForever(observer)
     }
 
     fun getAllTransaction() {
@@ -26,7 +26,7 @@ class ListTransactionViewModel(private var transactionRepository: TransactionRep
 
     override fun onCleared() {
         super.onCleared()
-        transactionRepository.getListTransactionLiveData().removeObserver(observer)
+        transactionRepository.listTransactionLiveData.removeObserver(observer)
     }
 
 
diff --git a/app/src/main/java/com/informatika/bondoman/viewmodel/transaction/UpdateTransactionViewModel.kt b/app/src/main/java/com/informatika/bondoman/viewmodel/transaction/UpdateTransactionViewModel.kt
index 16da0cb251f8038ea0a46eb038429c5ab6eea4fd..6576ced9fa836595198ba40de03438244b5838b6 100644
--- a/app/src/main/java/com/informatika/bondoman/viewmodel/transaction/UpdateTransactionViewModel.kt
+++ b/app/src/main/java/com/informatika/bondoman/viewmodel/transaction/UpdateTransactionViewModel.kt
@@ -5,27 +5,28 @@ import androidx.lifecycle.ViewModel
 import androidx.lifecycle.viewModelScope
 import com.informatika.bondoman.model.Resource
 import com.informatika.bondoman.model.local.entity.transaction.Transaction
-import com.informatika.bondoman.model.repository.TransactionRepository
+import com.informatika.bondoman.model.repository.transaction.TransactionRepository
 import com.informatika.bondoman.viewmodel.transaction.helper.TransactionFormState
 import kotlinx.coroutines.launch
 
-class UpdateTransactionViewModel(private var transactionRepository: TransactionRepository, transaction: Transaction) : ViewModel() {
+class UpdateTransactionViewModel(private var transactionRepository: TransactionRepository, _id: Int) : ViewModel() {
     val transactionLiveData = MutableLiveData<Resource<Transaction>>()
     private val observer = androidx.lifecycle.Observer<Resource<Transaction>> {
         transactionLiveData.postValue(it)
     }
 
+    // TODO: Implement updateTransaction function
     private val _updateTransactionForm = MutableLiveData<TransactionFormState>()
 
     init {
-        transactionRepository.getTransactionLiveData().observeForever(observer)
+        transactionRepository.transactionLiveData.observeForever(observer)
         viewModelScope.launch {
-            transactionRepository.getTransaction(transaction._id)
+            transactionRepository.getTransaction(_id)
         }
     }
 
     override fun onCleared() {
         super.onCleared()
-        transactionRepository.getTransactionLiveData().removeObserver(observer)
+        transactionRepository.transactionLiveData.removeObserver(observer)
     }
 }
\ No newline at end of file
diff --git a/app/src/test/java/com/informatika/bondoman/CheckAllModules.kt b/app/src/test/java/com/informatika/bondoman/CheckAllModules.kt
new file mode 100644
index 0000000000000000000000000000000000000000..9f1ea55c8e71cfd658ece845911be59cc2ab2aa4
--- /dev/null
+++ b/app/src/test/java/com/informatika/bondoman/CheckAllModules.kt
@@ -0,0 +1,28 @@
+package com.informatika.bondoman
+
+import android.app.Application
+import com.informatika.bondoman.di.applicationModule
+import com.informatika.bondoman.di.databaseModule
+import com.informatika.bondoman.di.networkModule
+import com.informatika.bondoman.di.repositoryModule
+import com.informatika.bondoman.di.viewModelModule
+import io.mockk.mockk
+import org.koin.android.ext.koin.androidContext
+import org.koin.core.context.startKoin
+import org.koin.dsl.koinApplication
+import org.koin.test.KoinTest
+import org.koin.test.check.checkModules
+import kotlin.test.Test
+
+class CheckAllModules: KoinTest {
+    private val mockApplication: Application = mockk()
+    @Test
+    fun checkAllModules() {
+        // Check all modules
+        startKoin {
+            androidContext(mockApplication)
+            modules(listOf(applicationModule, databaseModule, networkModule, repositoryModule, viewModelModule))
+        }.checkModules()
+
+    }
+}
\ No newline at end of file