'Android GeoFire and Firebase Unit Testing in Android Studio with Mockito

I want to write unit tests for this presenter class HomePresenter in Android Studio. However, I'm having trouble creating tests to cover both the geoQueryOnUserLocation method and the geoQueryOnSignLocation method due to using GeoFire and Firebase. I want to test this class using Mockito. Is there a good way to test this class?

HomePresenter.kt:

class HomePresenter(val view: HomeView, val context: Context, val activity: FragmentActivity) {
    private val mFirebaseDatabase = FirebaseDatabase.getInstance()
    private val mDatabaseReference = mFirebaseDatabase.reference
    private var mFirstSignKey: String? = "first_sign_key"
    private var mLastSignKey: String? = "last_sign_key"
    private var mGeoQueryOnSignLocation: GeoQuery? = null
    private var mGeoQueryOnMyLocation: GeoQuery? = null

    fun geoQueryOnUserLocation(lastLocation: Location?, radius: Double?, userAddress: String?) {
        mGeoQueryOnMyLocation =
            GeoFire(mDatabaseReference.child(CHILD_GEOFIRE_TYPE_1)).queryAtLocation(
                GeoLocation(
                    lastLocation?.latitude!!,
                    lastLocation.longitude
                ), radius?.div(1000)!!
            )
        mGeoQueryOnMyLocation?.addGeoQueryEventListener(object : GeoQueryEventListener {
            override fun onKeyEntered(key: String?, location: GeoLocation?) {
                mFirstSignKey = key
                if (mFirstSignKey != mLastSignKey) {
                    mDatabaseReference.child(CHILD_SIGNS).child(key!!)
                        .addListenerForSingleValueEvent(object : ValueEventListener {
                            override fun onDataChange(dataSnapshot: DataSnapshot) {
                                val sign = dataSnapshot.getValue(Sign::class.java)
                                if (sign?.address == userAddress) {
                                    view.onRetrieveLastSign(sign, key, TAG_SIGN_CAT_1)
                                    mLastSignKey = sign?.signId
                                }
                            }

                            override fun onCancelled(databaseError: DatabaseError) {
                                view.onFailure(databaseError.message, "")
                            }
                        })
                }
            }

            override fun onGeoQueryError(error: DatabaseError) {
                view.onFailure(error.message, "")
            }

            override fun onGeoQueryReady() {}
            override fun onKeyMoved(key: String?, location: GeoLocation?) {}
            override fun onKeyExited(key: String?) {}
        })
    }

    fun geoQueryOnSignLocation(listSign: ArrayList<Sign>) {
        if (mGeoQueryOnSignLocation != null) {
            mGeoQueryOnSignLocation?.removeAllListeners()
        }

        listSign.iterator().forEach {
            if (it.type == 0 || it.type == 1) {
                mGeoQueryOnSignLocation =
                    GeoFire(mDatabaseReference.child(CHILD_GEOFIRE_TYPE_0)).queryAtLocation(
                        GeoLocation(it.latitude, it.longitude),
                        0.015
                    )
                mGeoQueryOnSignLocation?.addGeoQueryEventListener(object : GeoQueryEventListener {
                    override fun onKeyEntered(key: String?, location: GeoLocation?) {
                        view.onRetrieveLastSign(it, key as String, TAG_SIGN_CAT_0_ENTERED)
                    }

                    override fun onKeyExited(key: String?) {
                        view.onRetrieveLastSign(it, key as String, TAG_SIGN_CAT_0_EXITED)
                    }

                    override fun onGeoQueryError(error: DatabaseError) {
                        view.onFailure(error.message, "")
                    }

                    override fun onKeyMoved(key: String?, location: GeoLocation?) {}
                    override fun onGeoQueryReady() {}
                })
            }
        }
    }
}

HomeFragment.kt:

class HomeFragment : Fragment(), HomeView {
    private lateinit var mPresenter: HomePresenter
    private var mUserLastLocation: Location? = null
    private var mUserLastSpeed: Float = 0.0f
    private var mUserLastRadius: Double? = null

    override fun onRetrieveLastLocation(lastLocation: Location, address: String?) {
        mUserLastLocation = lastLocation
        mUserLastSpeed = mUserLastLocation?.speed!!
        mUserLastRadius = mUserLastSpeed.times(mPrefNotificationTimeSignCat1 as Int).toDouble()
        mPresenter.geoQueryOnUserLocation(mUserLastLocation, mUserLastRadius, address)
    }

    override fun onLoadAllSigns(signs: ArrayList<Sign>) {
        mPresenter.updateSignLocationsToGeoFire(signs)
        mPresenter.geoQueryOnSignLocation(signs)
    }

    override fun onRetrieveLastSign(sign: Sign?, key: String, tag: String) {
        if (sign?.headingQuadrant != mUserLastLocation?.let { userBearingQuadrant(it) }) {
            if (tag == TAG_SIGN_CAT_1) {
                ...
            }
            if (tag == TAG_SIGN_CAT_0_ENTERED) {
                ...
            }
            if (tag == TAG_SIGN_CAT_0_EXITED) {
                ...
            }
        }
    }

    private fun userBearingQuadrant(location: Location): String {
        return if (location.bearing in 0.0..90.0) {
            "I"
        } else if (location.bearing > 90 && location.bearing <= 180) {
            "II"
        } else if (location.bearing > 180 && location.bearing <= 270) {
            "III"
        } else {
            "IV"
        }
    }
}


Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source