OkHttpClientのresponse.body?.string()が、try{}で囲まれると失敗する
- 失敗するコード
class WebApiClientImpl @Inject constructor( private val injectableConstants: InjectableConstants, private val authStateManager: AuthStateManager, private val okHttpClient: OkHttpClient, private val gson: Gson ) : WebApiClient { // Get User's Saved Shows override suspend fun getUsersSavedShows(): PagingObject<ItemShow> { val url = injectableConstants.baseUrl + "/me/shows"; // Make a request to API endpoint. val request = Request.Builder() .url(url) .header("Content-Type", "application/json") .header("Authorization", "Bearer ${authStateManager.authState.accessToken}") .build() return withContext(Dispatchers.IO) { try { val response = okHttpClient.newCall(request).execute() if (!response.isSuccessful) { throw Exception(response.toString()) } val tokenType = object : TypeToken<PagingObject<ItemShow>>() {}.type var respString = response.body?.string() gson.fromJson( respString, tokenType ) } catch (e: Exception){ throw e } } } }
- テストコード
@SmallTest class InstrumentedUnitTest{ companion object { lateinit var localKeyValueStorageImpl: LocalKeyValueStorageImpl lateinit var remoteDataSourceImpl: RemoteDataSourceImpl lateinit var mainRepository: MainRepository lateinit var mockWebServer: MockWebServer @BeforeClass @JvmStatic fun init() { // Context of the app under test. val context = InstrumentationRegistry.getInstrumentation().targetContext val mainKey = MasterKey.Builder(context) .setKeyScheme(MasterKey.KeyScheme.AES256_GCM) .build() // Backup the initial AuthState value. val prefs = EncryptedSharedPreferences.create( context, Constants.shared_prefs_file, mainKey, EncryptedSharedPreferences.PrefKeyEncryptionScheme.AES256_SIV, EncryptedSharedPreferences.PrefValueEncryptionScheme.AES256_GCM ) // Init for storage, remotedatasource and repository. val okHttpClient = OkHttpClient() localKeyValueStorageImpl = LocalKeyValueStorageImpl(prefs) val authStateManager = AuthStateManager(localKeyValueStorageImpl) authStateManager.authService = AuthorizationService(context) val gson = Gson() val injectableConstants = InjectableConstants( baseUrl = "http://localhost:8080" ) val webApiClientImpl = WebApiClientImpl(injectableConstants ,authStateManager, okHttpClient, gson) remoteDataSourceImpl = RemoteDataSourceImpl(webApiClientImpl, LocalKeyValueStorageImpl(prefs)) mainRepository = MainRepositoryImpl(remoteDataSourceImpl) // mock web server mockWebServer = MockWebServer() mockWebServer.start(8080) } @AfterClass @JvmStatic fun end(){ mockWebServer.shutdown() } } @Test fun get_following_shows() = runBlocking{ val successResponseData = """ { // JSONデータ。中身省略 "total": 15 } """ val successResponse = MockResponse().apply { setResponseCode(200) setHeader("Content-Type", "application/json") setBody(successResponseData) } mockWebServer.enqueue(successResponse) val result = mainRepository.getUsersSavedShows() assertEquals(15, result.items.count()) } }
- エラーメッセージ
cannot be cast to java.lang.Void
- 修正後コード(抜粋)
// Get User's Saved Shows override suspend fun getUsersSavedShows(): PagingObject<ItemShow> { val url = injectableConstants.baseUrl + "/me/shows"; // Make a request to API endpoint. val request = Request.Builder() .url(url) .header("Content-Type", "application/json") .header("Authorization", "Bearer ${authStateManager.authState.accessToken}") .build() return withContext(Dispatchers.IO) { val response = okHttpClient.newCall(request).execute() if (!response.isSuccessful) { throw Exception(response.toString()) } val tokenType = object : TypeToken<PagingObject<ItemShow>>() {}.type var respString = response.body?.string() gson.fromJson( respString, tokenType ) } }