LoginSignup
1
1

More than 1 year has passed since last update.

[Android]kotlin+firestore emulatorを使ったunit testを構築する

Last updated at Posted at 2022-03-02

こんにちは。virapture株式会社のもぐめっとです。

IMG_76DCF03199D4-1.jpeg

最近もっぱら休みの日は山にこもって雪山に土下座する毎日なので自分の顔写真がないのが最近の悩みです。

本日はfirestoreのエミュレータを使ったunit testの方法について紹介します。

事前準備

firebaseコマンドでエミュレータを起動できるようにしておきます。

npm install -g firebase-tools
cd {firebase.jsonを定義してるところがあるのディレクトリ}

firebase.jsonがなければ下記コマンドでプロジェクトの設定をしましょう。

firebase init

emulatorを起動します。

firebase start emulator

これで準備おk!

unit testの準備

肝としては2点あります。
それが、emulatorを使うようにする設定と、testの度にデータを削除する仕組みです。

emulatorを使うようにするには下記のような書き方を行います。

val firestoreHost = "10.0.2.2"
val firestorePort = 8080
val db = Firebase.firestore.apply {
    this.useEmulator(firestoreHost, firestorePort)
    this.firestoreSettings = firestoreSettings {
        isPersistenceEnabled = false
    }
}

データの削除はどうやるかなんですが、実はemulatorにはAPIがあって、それを叩くことでデータの削除を行います。

suspend fun deleteData() = withContext(Dispatchers.IO) {
    val projectName = "hoge"
    val url =
        URL("http://${firestoreHost}:${firestorePort}/emulator/v1/projects/${projectName}/databases/(default)/documents")
    val con = (url.openConnection() as HttpURLConnection).apply {
        this.requestMethod = "DELETE"
        this.instanceFollowRedirects = false
        this.connectTimeout = 5000
        this.readTimeout = 5000
        this.setRequestProperty("Content-Type", "application/json; charset=utf-8")
    }
    con.responseCode
    con.disconnect()
}

ということでこれらをいい感じに纏めたUtilを用意しておきます。

class FirestoreTestUtil {
    companion object {
        private const val firestoreHost = "10.0.2.2"
        private const val firestorePort = 8080
        val db = Firebase.firestore.apply {
            useEmulator(firestoreHost, firestorePort)
            firestoreSettings = firestoreSettings {
                isPersistenceEnabled = false
            }
        }

        suspend fun deleteData() = withContext(Dispatchers.IO) {
            val projectName = "hoge"
            val url =
                URL("http://${firestoreHost}:${firestorePort}/emulator/v1/projects/${projectName}/databases/(default)/documents")
            val con = (url.openConnection() as HttpURLConnection).apply {
                requestMethod = "DELETE"
                instanceFollowRedirects = false
                connectTimeout = 5000
                readTimeout = 5000
                setRequestProperty("Content-Type", "application/json; charset=utf-8")
            }
            con.responseCode
            con.disconnect()
        }
    }
}

実際にエミュレータを使ったunit testを書く

先程作ったutilを使ってこんな感じで書きます。

@ExperimentalCoroutinesApi
class CustomerRepositoryTest {
    private var db = FirestoreTestUtil.db

    companion object {
        @BeforeClass @JvmStatic
        fun setup() {
            runBlocking {
                FirestoreTestUtil.deleteData()
            }
        }
    }
    @Before
    fun before() {
        val collection = db.collection("customers")
        val customerData = mapOf(
            "firstName" to "Test",
            "lastName" to "Customer",
            "createdAt" to Timestamp.now(),
            "updatedAt" to Timestamp.now()
        )
        collection.document("testcustomer").set(customerData)
    }

    @After
    fun tearDown() {
        runBlocking {
            FirestoreTestUtil.deleteData()
        }
    }

    @Test
    fun findById() = runTest {
        val repository = CustomerRepository(db)
        val customer = repository.findById("testcustomer")
        assertNotNull(customer)
        customer?.run {
            assertEquals("Test", firstName)
            assertEquals("Customer", lastName)
        }
    }
}

まとめ

androidとfirestoreでもemulatorを使ったunit testを無事書くことができるようになりました!
削除するときに癖がちょっとありますが、これでいい感じにできるはずです!

これでよいTDDライフを送れることでしょう!

最後に、ワンナイト人狼オンラインというゲームを作ってます!よかったら遊んでね!

他にもCameconOffchaといったサービスも作ってるのでよかったら使ってね!

また、チームビルディングや技術顧問、Firebaseの設計やアドバイスといったお話も受け付けてますので御用の方は弊社までお問い合わせください。

1
1
0

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
1
1