LoginSignup
9

More than 5 years have passed since last update.

Retrofit-MockでWebAPIをモック化する

Last updated at Posted at 2018-01-26

はじめに

Androidアプリを作る際、WebAPIの仕様は決まっているものの、実際動くものがまだないということはよくあると思います。そんな時にRetrofitMockを使ってWebAPIをモック化することで、スムーズにアプリ開発を行うことができ、またWebAPIが使えるようになった時もスムーズに移行することができます。

RetrofitMock
https://github.com/square/retrofit/tree/master/retrofit-mock

今回は、Retrofit2 + RxJavaでWebAPIを利用するコードに、RetrofitMockを組み込みます。

環境

Kotlin
Retrofit2
RxJava
RetrofitMock
Moshi

セットアップ

gradle.build
    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

QiitaTag.kt
data class QiitaTag(
        var followers_count: Int,
        var icon_url: String?,
        var id: String,
        var items_count: Int
)

RetrofitでAPI定義

今回はタグ一覧の取得APIのみ定義

IQiitaApi.kt
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%に変更。

QiitaApi.kt
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"のパーミッションが必要になります。

QiitaApiTest.kt
@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
                }
    }
}

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
9