はじめに
Androidアプリを作る際、WebAPIの仕様は決まっているものの、実際動くものがまだないということはよくあると思います。そんな時にRetrofitMockを使ってWebAPIをモック化することで、スムーズにアプリ開発を行うことができ、またWebAPIが使えるようになった時もスムーズに移行することができます。
RetrofitMock
https://github.com/square/retrofit/tree/master/retrofit-mock
今回は、Retrofit2 + RxJavaでWebAPIを利用するコードに、RetrofitMockを組み込みます。
環境
Kotlin
Retrofit2
RxJava
RetrofitMock
Moshi
セットアップ
implementation 'com.squareup.retrofit2:retrofit:2.3.0'
implementation "com.squareup.retrofit2:adapter-rxjava2:2.3.0"
implementation 'com.squareup.retrofit2:converter-moshi:2.2.0'
implementation 'com.squareup.retrofit2:retrofit-mock:2.3.0'
データクラス定義
今回はタグ一覧の取得APIのみ定義するため、Tagを表すデータクラスを作成
https://qiita.com/api/v2/docs#get-apiv2tags
data class QiitaTag(
var followers_count: Int,
var icon_url: String?,
var id: String,
var items_count: Int
)
RetrofitでAPI定義
今回はタグ一覧の取得APIのみ定義
interface IQiitaApi {
/**
* https://qiita.com/api/v2/docs#get-apiv2tags
*/
@GET("api/v2/tags")
fun tags(
@Query("page") page: Int? = null,
@Query("per_page") per_page: Int? = null,
@Query("sort") sort: String? = null
): Observable<List<QiitaTag>>
}
API呼び出し用オブジェクト生成
通常呼び出し用のcreate関数と、Mock作成用のcreateMock関数を作成。
注意点はNetworkBehaviorはデフォルトで応答するまで2000msになっているのでテストの効率を上げるため100msに変更。失敗率もデフォルトで3%になっており、たまにテストに失敗するため0%に変更。
class QiitaApi {
companion object {
fun create(): IQiitaApi {
val retrofit = Retrofit.Builder()
.addCallAdapterFactory(RxJava2CallAdapterFactory.create())
.addConverterFactory(MoshiConverterFactory.create())
.baseUrl("https://qiita.com/")
.build()
return retrofit.create(IQiitaApi::class.java)
}
fun createMock(): IQiitaApi {
val retrofit = Retrofit.Builder()
.addCallAdapterFactory(RxJava2CallAdapterFactory.create())
.addConverterFactory(MoshiConverterFactory.create())
.baseUrl("http://example.com")
.build()
val behavior = NetworkBehavior.create()
behavior.setDelay(100, TimeUnit.MILLISECONDS)
behavior.setFailurePercent(0)
behavior.setErrorPercent(0)
val mockRetrofit = MockRetrofit.Builder(retrofit)
.networkBehavior(behavior)
.build()
val delegate = mockRetrofit.create(IQiitaApi::class.java)
return MockQiitaApi(delegate)
}
}
}
テスト
androidTestでテストを実施。
テスト内容は適当ですが、エラーが発生しないこと、アイテム数が意図したものであることを確認。
QiitaのAPIとMockAPIで同じように呼び出しとテストができます。
インターネットに接続するため、"android.permission.INTERNET"のパーミッションが必要になります。
@RunWith(AndroidJUnit4::class)
class QiitaApiTest {
@Test
fun qiitaApi() {
val api = QiitaApi.create()
api.tags()
.test()
.assertNoErrors()
.assertValue{
it.size == 20
}
}
@Test
fun mockApi() {
val mock = QiitaApi.createMock()
mock.tags()
.test()
.assertNoErrors()
.assertValue {
it.size == 10
}
}
}