如何测试具有由 android 生成的接口依赖项的 ViewModel class 作为单元测试

How do I test a ViewModel class which has an interface dependecy that is generated by android as a Unit Test

大家好,我正在尝试测试我的 ViewModel class,它依赖于数据源,我试图模拟它,但它不会工作,因为它是一个接口,我相信接口实现在运行时生成,我如何对这个 class 进行单元测试,下面是我的 ViewModel class

class LoginViewModel @ViewModelInject constructor(@ApplicationContext private val context: Context,
                                                 private val networkApi: NetworkAPI,
                                                 private val dataStore: DataStore<Preferences>)
   : ViewModel() {


   val clientNumber = MutableLiveData<String>()
   val clientPassword = MutableLiveData<String>()

   private val _shouldNavigate = MutableLiveData(false)
   val shouldNavigate: LiveData<Boolean>
       get() = _shouldNavigate

   private val _errorMessage = MutableLiveData<String>()
   val errorMessage: LiveData<String>
       get() = _errorMessage

private val _activateDeviceButton = MutableLiveData(false)
   val activateButton : LiveData<Boolean>
   get() = _activateDeviceButton

   init {
       populateApiWithFakeData()
   }


   suspend fun authenticateUsers(): Boolean {
       val clientNumber = clientNumber.value
       val clientPassword = clientPassword.value
       requireNotNull(clientNumber)
       requireNotNull(clientPassword)
       val (userExist, token) = networkApi.doesUserExist(clientNumber.toLong(), clientPassword)
       if (token.isNotBlank()) storeTokenInStore(token)
       return if (userExist) {
           true
       } else {
           _errorMessage.value = "Incorrect account details. Please try again with correct details"
           false
       }
   }

  private suspend fun storeTokenInStore(token: String) {
       dataStore.edit { pref ->
           pref[TOKEN_PREFERENCE] = token
       }
   }


这是我的 ViewModel 测试 class

@Config(sdk = [Build.VERSION_CODES.O_MR1])
@RunWith(AndroidJUnit4::class)
class LoginViewModelTest{


    private val context : Context = ApplicationProvider.getApplicationContext()

    private val dataCentre = NetworkApImpl()

    @Mock
    private lateinit var dataStore: DataStore<Preferences>

    @Before
    fun setUpDataCenters(){
        val loginData = DataFactory.generateLoginData()
        for (data in loginData){
            dataCentre.saveUserData(data)
        }
    }

    @After
    fun tearDownDataCenter(){
        dataCentre.clearDataSet()
    }

    @Test
    @ExperimentalCoroutinesApi
    fun authenticateUser_shouldAuthenticateUsers(){
        //Given
        val viewModel = LoginViewModel(context, dataCentre, dataStore)
        viewModel.clientNumber.value = "8055675745"
        viewModel.clientPassword.value = "robin"
        //When
        var result : Boolean? = null
        runBlocking {
            result = viewModel.authenticateUsers()
        }
        //Then
        Truth.assertThat(result).isTrue()
    }

如有任何帮助,我们将不胜感激。

您可以按照 Mockito 的建议 here 将您的依赖项包装在您拥有的 class 中。这还有一个好处,那就是让您可以在以后更改存储实现,而不会影响使用它的每个视图模型。