开发者

How can I write an Android unit test that depends on location updates?

I have an app that displays the Maidenhead grid square corresponding to that location. I would like to write a unit test for this feature.

I have created a mock location provider. When I stick the mock provider into my app, I see the expected Maidenhead grid square on the display. When I stick the mock provider into my test project and check the view it never updates, even when I call Thread.sleep() or waitOnIdleSync().

I would directly test the method that computes the actual grid square but it is private, and there's no way to test private methods. All 开发者_如何学编程the example code I have seen online for unit tests that check views is for apps like calculators, where activity is triggered by fake button presses.

Here is the code for the test:

    public void testMaidenhead() {
        // this is a single test which doesn't really validate the algorithm
        // identifying a bunch of edge cases would do that
        publishMockLocation();
        final String expectedMH = "CM87wk";
        // TODO: checking the textview does not work
        TextView mhValueView = (TextView) mActivity.findViewById(org.twilley.android.hfbeacon.R.id.maidenheadValue);
        String actualMH = mhValueView.getText().toString();
        // final String actualMH = mActivity.gridSquare(mLocation);
        assertEquals(expectedMH, actualMH);
    }

And here is the code for publishing the mock location:

    protected void publishMockLocation() {
        final double TEST_LONGITUDE = -122.084095;
        final double TEST_LATITUDE = 37.422006;
        final String TEST_PROVIDER = "test";
        final Location mLocation;
        final LocationManager mLocationManager;

        mLocationManager = (LocationManager) mActivity.getSystemService(Context.LOCATION_SERVICE);
        if (mLocationManager.getProvider(TEST_PROVIDER) != null) {
            mLocationManager.removeTestProvider(TEST_PROVIDER);
        }
        if (mLocationManager.getProvider(TEST_PROVIDER) == null) {
            mLocationManager.addTestProvider(TEST_PROVIDER, 
                false, //requiresNetwork,
                false, // requiresSatellite,
                false, // requiresCell,
                false, // hasMonetaryCost,
                false, // supportsAltitude,
                false, // supportsSpeed,
                false, // supportsBearing,
                android.location.Criteria.POWER_MEDIUM, // powerRequirement
                android.location.Criteria.ACCURACY_FINE); // accuracy
        }
        mLocation = new Location(TEST_PROVIDER);
        mLocation.setLatitude(TEST_LATITUDE);
        mLocation.setLongitude(TEST_LONGITUDE);
        mLocation.setTime(System.currentTimeMillis());
        mLocation.setAccuracy(25);
        mLocationManager.setTestProviderEnabled(TEST_PROVIDER, true);
        mLocationManager.setTestProviderStatus(TEST_PROVIDER, LocationProvider.AVAILABLE, null, System.currentTimeMillis());
        mLocationManager.setTestProviderLocation(TEST_PROVIDER, mLocation);
    }

Any help would be dearly appreciated. Thank you in advance!

Jack.


Unit testing would not be to make your phone fake its GPS location so it shows you the Maidenhead for the location you want to test. Unit testing would be: write a function that takes WGS84 GPS coordinates and outputs Maidenhead, and write a couple of tests for a series of input locations and outputs to make sure your function works as you need.

Testing the actual Android activity would be integration or acceptance testing, but the actual coordinate to Maidenhead functionality should work as you unit tested it.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜