Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 31 additions & 0 deletions core/src/main/java/com/example/core/network/MockUtils.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package com.example.core.network

import android.content.Context
import com.squareup.moshi.Moshi
import com.squareup.moshi.Types
import com.squareup.moshi.kotlin.reflect.KotlinJsonAdapterFactory

inline fun <reified T> parseJsonFromAssets(context: Context, fileName: String): T? {
return try {
val json = context.assets.open(fileName).bufferedReader().use { it.readText() }
val moshi = Moshi.Builder().add(KotlinJsonAdapterFactory()).build()
val adapter = moshi.adapter(T::class.java)
adapter.fromJson(json)
} catch (e: Exception) {
e.printStackTrace()
null
}
}

inline fun <reified T> parseJsonListFromAssets(context: Context, fileName: String): List<T> {
return try {
val json = context.assets.open(fileName).bufferedReader().use { it.readText() }
val moshi = Moshi.Builder().add(KotlinJsonAdapterFactory()).build()
val type = Types.newParameterizedType(List::class.java, T::class.java)
val adapter = moshi.adapter<List<T>>(type)
adapter.fromJson(json) ?: emptyList()
} catch (e: Exception) {
e.printStackTrace()
emptyList()
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,43 +2,28 @@ package com.example.feature.recipe.impl.data.repository

import android.content.Context
import com.example.core.domain.DomainResult
import com.example.core.network.parseJsonFromAssets
import com.example.feature.recipe.api.data.RecipeRepository
import com.example.feature.recipe.api.domain.model.Recipe
import com.example.feature.recipe.impl.data.ApiRecipeListResponse
import com.example.feature.recipe.impl.data.ApiRecipeMapper
import com.squareup.moshi.Moshi
import java.io.InputStream
import javax.inject.Inject

class RecipeRepositoryMockImpl @Inject constructor(
private val context: Context,
private val mapper: ApiRecipeMapper,
private val moshi: Moshi,
) : RecipeRepository {

override suspend fun getRecipes(): DomainResult<List<Recipe>> {
return try {
val json = readJsonFromAssets("recipe_mock.json")
val adapter = moshi.adapter(ApiRecipeListResponse::class.java)
val response: ApiRecipeListResponse? = adapter.fromJson(json)
val response = parseJsonFromAssets<ApiRecipeListResponse>(
context,
"recipe_mock.json",
)
val recipes: List<Recipe> = response?.let { mapper.map(it) } ?: emptyList()
DomainResult.Success(recipes)
} catch (e: Exception) {
DomainResult.Error("Failed to load mock recipes: ${e.message}")
}
}

private fun readJsonFromAssets(fileName: String): String {
return try {
val inputStream: InputStream = context.assets.open(fileName)
val size: Int = inputStream.available()
val buffer = ByteArray(size)
inputStream.read(buffer)
inputStream.close()
String(buffer, Charsets.UTF_8)
} catch (e: Exception) {
e.printStackTrace()
""
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ class RecipeApiTest : ApiAbstract<RecipeApi>() {
@Test
fun `test getRecipes request path is correct`() = runBlocking {
// Given
enqueueResponse("/recipes.json")
enqueueResponse("recipes.json")

// When
apiService.getRecipes()
Expand All @@ -40,7 +40,7 @@ class RecipeApiTest : ApiAbstract<RecipeApi>() {
@Test
fun `test getRecipes returns list of recipes`() = runBlocking {
// Given
enqueueResponse("/recipes.json")
enqueueResponse("recipes.json")

// When
val response = apiService.getRecipes()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import android.content.Context
import com.example.feature.recipe.api.data.RecipeRepository
import com.example.feature.recipe.impl.data.ApiRecipeMapper
import com.example.feature.recipe.impl.data.repository.RecipeRepositoryMockImpl
import com.squareup.moshi.Moshi
import dagger.Module
import dagger.Provides
import dagger.hilt.InstallIn
Expand All @@ -21,9 +20,8 @@ object RecipeMockModule {
fun provideRecipeRepository(
@ApplicationContext context: Context,
mapper: ApiRecipeMapper,
moshi: Moshi,
): RecipeRepository {
// Ensure we use application context, which is properly injected by Hilt
return RecipeRepositoryMockImpl(context.applicationContext, mapper, moshi)
return RecipeRepositoryMockImpl(context.applicationContext, mapper)
}
}
5 changes: 3 additions & 2 deletions test-utils/src/main/java/com/example/testutils/ApiAbstract.kt
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,9 @@ abstract class ApiAbstract<T> {
}

@Throws(IOException::class)
private fun enqueueResponse(fileName: String, headers: Map<String, String>) {
val inputStream = javaClass.classLoader!!.getResourceAsStream("api-response/$fileName")
fun enqueueResponse(fileName: String, headers: Map<String, String>) {
val inputStream = javaClass.classLoader?.getResourceAsStream("api-response/$fileName")
?: throw IOException("File not found: api-response/$fileName")
val source = inputStream.source().buffer()
val mockResponse = MockResponse()
for ((key, value) in headers) {
Expand Down