Sobes.tech
Intern

How did you perform the test assignment and what materials did you use for it?

sobes.tech AI

Answer from AI

For the test task, I used Kotlin as the main programming language because it is recommended for Android development and offers many advantages such as safety, conciseness, and interoperability with Java.

As an architectural pattern, I chose MVVM (Model-View-ViewModel) because it provides good separation of responsibilities, simplifies testing, and improves maintainability of the code.

For asynchronous operations and thread management, Coroutines were used, providing a lightweight and flexible solution for parallel programming in Kotlin.

For network requests, the Retrofit library was used in conjunction with Moshi for JSON parsing. Retrofit simplifies executing HTTP requests, and Moshi is an efficient JSON parser.

Dependency management and injection were handled using Hilt, a Dagger extension that simplifies setup and use of dependency injection in Android applications.

For data storage, the Room Persistence Library was used, an abstraction over SQLite that simplifies working with databases on Android.

The main materials I used include:

  • Official Kotlin documentation (kotlinlang.org)
  • Official Android Developers documentation (developer.android.com)
  • Documentation for the libraries used (Retrofit, Moshi, Hilt, Room, Coroutines)
  • Articles and video tutorials on platforms like Medium, ProAndroidDev, YouTube channels

Example of using Coroutines:

// Launching a coroutine in ViewModel scope
viewModelScope.launch {
    // Performing a network request in the background thread
    val result = withContext(Dispatchers.IO) {
        repository.getSomeData()
    }
    // Updating UI on the main thread
    _data.value = result
}

Example of using Room:

// Defining a Room entity
@Entity
data class User(
    @PrimaryKey val id: Int,
    val name: String
)

// Defining DAO
@Dao
interface UserDao {
    @Query("SELECT * FROM user")
    fun getAll(): LiveData<List<User>>

    @Insert
    suspend fun insertAll(vararg users: User)
}

// Defining the database
@Database(entities = [User::class], version = 1)
abstract class AppDatabase : RoomDatabase() {
    abstract fun userDao(): UserDao
}

The MVVM architectural pattern was implemented as follows:

  • Model: Repositories that abstract data sources (network, database) and provide data to ViewModel.
  • View: UI components (Activity, Fragment) that display data and send events to ViewModel.
  • ViewModel: Holds UI state, interacts with the Model, and provides data to the View via LiveData or StateFlow.

Testing was performed using JUnit for unit tests, Mockito (for mocking dependencies), and AndroidX Test (for instrumental tests).

// Example of a unit test with JUnit and Mockito
@Test
fun `getUserData should return data from repository`() {
    // Arrange
    val expectedUser = User(1, "Test User")
    whenever(repository.getUser(anyInt())).thenReturn(expectedUser)
    
    // Act
    val actualUser = viewModel.getUserData(1)
    
    // Assert
    assertEquals(expectedUser, actualUser)
}