首页 > 解决方案 > 在android中,如何对一个类进行单元测试等于另一个类,其中两个类都被包装类包装

问题描述

我正在使用包装类GenericApiResponse进行 api 响应:

sealed class GenericApiResponse<T> {

    companion object {
     fun <T> create(error: Throwable): ApiErrorResponse<T> {
        return ApiErrorResponse(error.message ?: "unknown error") }

    fun <T> create(response: Response<T>): GenericApiResponse<T> {

           if(response.isSuccessful){
               val body = response.body()
               if (body == null || response.code() == 204) {
               return ApiEmptyResponse()    }
           else if(response.code() == 401){  return ApiErrorResponse("401 Unauthorized. Token may be invalid.")     }
           else {   return ApiSuccessResponse(body = body)}
        }
        else{
          val msg = response.errorBody()?.string()
          val errorMsg = if (msg.isNullOrEmpty()) {
            response.message()
           } else {
            msg     }
         return ApiErrorResponse(errorMsg ?: "unknown error")
        }
    }   }
}


class ApiEmptyResponse<T> : GenericApiResponse<T>()

data class ApiSuccessResponse<T>(val body: T) : GenericApiResponse<T>() {}

data class ApiErrorResponse<T>(val errorMessage: String) : GenericApiResponse<T>()

并从我的 ViewModel MainViewModel我从我的MainRepository类调用一个函数:

 class MainViewModel @Inject constructor(val mainRepository: MainRepository) : ViewModel() {
.....
val source: LiveData<GenericApiResponse<GitResult>> = mainRepository.fetchApiresultFromClient(str_query)  
}

所以在MainRepository它调用:

class MainRepository @Inject constructor(val mainApiClient: MainApiClient) {
    ....
    fun fetchApiresultFromClient(strQuery: String)
         : LiveData<GenericApiResponse<GitResult>> {

          var returnedData =    mainApiClient.getApiResultFromServer(strQuery)
          return returnedData
     }

MainApiClient

class MainApiClient  @Inject constructor(val mainApi: MainApi) {
   fun getApiResultFromServer(query :String )
        : LiveData<GenericApiResponse<GitResult>> {

    var apiResult =   mainApi.getAllRepo(query)
       return apiResult
    }
}

MainApi:是用于改造的接口

一切正常,但是在尝试为应用程序实现一些单元测试代码时遇到了一些问题。我想断言,当从 viewModel 调用方法时,返回的数据是:

到目前为止,我已经尝试过:

  @ExtendWith(InstantExecutorExtension::class)
  class MainViewModelTest {

    lateinit var  mainViewModel: MainViewModel

    @Mock
     lateinit var  mainRepository: MainRepository

    @Mock
    lateinit var  mainApiClient: MainApiClient


    @BeforeEach
    fun init()
    {
    MockitoAnnotations.initMocks(this)
    mainViewModel = MainViewModel(mainRepository)
    }

    @Test
    fun setSearchQuery_callsRepositoryMethod_returnSuccess() {

           //arrange
         mainViewModel.liveResult.value = ApiSuccessResponse(TestUtil.obj_gitresult) as GenericApiResponse<GitResult>

        Mockito.`when`(mainApiClient.getApiResultFromServer(ArgumentMatchers.anyString(), ArgumentMatchers.anyInt()))
            .thenReturn(mainViewModel.liveResult)


           //act

        var repo_response = mainRepository.fetchApiresultFromClient("java")


        //assert
           // assertTrue(repo_response.value is  GenericApiResponse<GitResult> ) //for asserting return type is of type GenericResponse //--TestResult- java.lang.NullPointerException
           // assertTrue(repo_response.value is  ApiSuccessResponse<GitResult> ) //for asserting return type is of type ApiSuccessResponse //--TestResult- java.lang.NullPointerException
           //  assertEquals(mainViewModel.liveResult.value , repo_response.value ) //for asserting 2 generic types are equal //--TestResult- java.lang.NullPointerException
        }

}

但我用于测试的所有 3 个案例都失败并显示结果 java.lang.NullPointerException。

我究竟做错了什么?如何解决?如何编写测试上述所有案例的函数?

标签: androidunit-testingkotlinmockito

解决方案


推荐阅读