Android InstrumentedTest FusedLocationProviderClient mockLocation

35 Views Asked by At

So i try to do instrumented test for a function that get the gps coordinate of the devic

this is my code where i use the provider client to get the location and pass it to the callback:

@SuppressLint("MissingPermission")
private fun locationUpdate(locationProvider: FusedLocationProviderClient) {
    Log.d(TAG, "IN LOCATION UPDATE")
    locationCallback.let {
        val locationRequest =
            LocationRequest.Builder(
                Priority.PRIORITY_HIGH_ACCURACY,
                TimeUnit.SECONDS.toMillis(120)
            )
                .setWaitForAccurateLocation(true)
                .setMinUpdateIntervalMillis(2000)
                .setMaxUpdateDelayMillis(100)
                .build()
        locationProvider.requestLocationUpdates(
            locationRequest,
            it,
            Looper.getMainLooper()
        )
    }
}

and this is the core of the callback:

locationCallback = object : LocationCallback() {

            override fun onLocationResult(result: LocationResult) {
                result ?: return
                for (location in result.locations){
                    Log.d(TAG, "LOCATION: $location")

                    returnedLocation["x"] = location.latitude
                    returnedLocation["y"] = location.longitude
                    returnedLocation["z"] = location.altitude

                    stopLocationUpdate(locationProvider)
                    onLocationReceivedCallback(returnedLocation)
                }
            }
        }

and the "prototype" of the function:

fun getUserLocation(
    locationProvider: FusedLocationProviderClient,
    onLocationReceivedCallback: (coordinate: MutableMap<String, Double>) -> Unit
)

this is my test class:

class LocationTest {
    @get:Rule
    val composeTestRule = createComposeRule()

    lateinit var locationProviderClient: FusedLocationProviderClient

    fun getLocationProvider(
        context: Context,
        ): FusedLocationProviderClient {
        locationProviderClient = LocationServices
            .getFusedLocationProviderClient(context)

        locationProviderClient.setMockMode(true)


        return locationProviderClient
    }

    fun getLocation(
        lat: Double,
        long: Double,
        alt: Double,
        provider: String = LocationManager.GPS_PROVIDER
    ): Location{
        val location = Location(provider)

        location.latitude = lat
        location.longitude = long
        location.altitude = alt

        location.accuracy = 3.0f

        location.time = System.currentTimeMillis()

        return location
    }

    @Test
    fun getUserLocation_received_location_test(){
        val lat = 35.54677
        val long = -78.3423134
        val alt = 100.0

        var receivedLat: Double? = null
        var receivedLong: Double? = null
        var receivedAlt: Double? = null

        val location = getLocation(
            lat = lat,
            long = long,
            alt = alt
        )
        composeTestRule
            .setContent {
                val context = LocalContext.current
                val providerClient = getLocationProvider(
                    context,
                )
                providerClient.setMockLocation(location)
                
                getUserLocation(
                    locationProvider = providerClient,
                    onLocationReceivedCallback = { coordinates ->
                        receivedLat = coordinates["x"] ?: 0.0
                        receivedLong = coordinates["y"] ?: 0.0
                        receivedAlt = coordinates["z"] ?: 0.0
                    }
                )

            }


        assertEquals(lat, receivedLat)
        assertEquals(long, receivedLong)
        assertEquals(alt, receivedAlt)
    }

}

this didn'T work i never get my coordinate from my function to test,

if i manually got the user location with providerClient.lastLocation, then i received the location i set

i spent few days already trying to figure this out, but i'm still not sure how to make it work so any help would be great

0

There are 0 best solutions below