eaglesakuraの技術ブログ

技術的な話題とか、メモとか。

ライブラリプロジェクトでFirebase SDKを使ったUnitTestを動作させる

なぜコレが必要か?

  • Firebase SDKを組み込んだ処理は、通常 Google Services Plugingoogle-services.json をアプリに組み込むことで動作する
  • このPluginはApplicationビルド用のプロジェクトでしか動作しない
  • ライブラリプロジェクトにFirebase SDKを組み込んだ場合、上記の前提だとUnitTestをするためのApplicationプロジェクトが必要になってしまう
  • 明示的な初期化を行うことで、ライブラリプロジェクトだけでUnitTestが行える

方法

@RunWith(AndroidJUnit4::class)
class HogeTest {
   @Before
   fun before() {
        FirebaseApp.initializeApp(context, FirebaseOptions.Builder().also {
            it.setApiKey("hoge-fuga")
            it.setGcmSenderId("hoge-fuga")
            it.setStorageBucket("your-project.appspot.com")
            it.setProjectId("your-project")
            it.setApplicationId("hoge-fuga")
            it.setDatabaseUrl("https://your-project.firebaseio.com")
        }.build())
    }
}

通常自動的に行われる初期化を、手動でやることでUnitTestで動作するようになる。 ただし、InstrumentationTestでしか動かない(Firebaseの動作にGooglePlayServiceが必要)。

方法をスマートに

google-services.jsonandroidTest/assets に配置してロードすることで、ある程度勝手に初期化できるようになる。

            val json = ... // assetsからgoogle-services.jsonを読む
            FirebaseApp.initializeApp(context, FirebaseOptions.Builder().also { builder ->
                val root = JSONObject(json)
                root.getJSONObject("project_info").also { values ->
                    builder.setDatabaseUrl(values["firebase_url"].toString())
                    builder.setGcmSenderId(values["project_number"].toString())
                    builder.setProjectId(values["project_id"].toString())
                    builder.setStorageBucket(values["storage_bucket"].toString())
                }
                root.getJSONArray("client").getJSONObject(0).also { client ->
                    client.getJSONObject("client_info").also { values ->
                        builder.setApplicationId(values["mobilesdk_app_id"].toString())
                    }
                    client.getJSONArray("api_key").getJSONObject(0).also { apiKey ->
                        builder.setApiKey(apiKey["current_key"].toString())
                    }
                }
            }.build())