Тестирование макетов не работает - PullRequest
0 голосов
/ 13 марта 2012
I have written a simple Gps Service. Now I am writing a testcase for testing it. I am trying to send a mock location but the onLocation changed is not getting called in my GpsService location listener.

Here is my GpsService








/**
* returns the binder object that client of this can bind to
*/
@Override
public IBinder onBind(Intent arg0) {

    return mBinder;
}

@Override
public void onCreate() {
    super.onCreate();
    Log.e("GpsService","StartService");


}

private class MyLocationListener implements  LocationListener {

    @Override
    public void onLocationChanged(Location loc) {
        Log.e("GpsService","Location in GpsService"+loc.toString());
        if(loc.hasAccuracy() && loc.getAccuracy() <= minAccuracyMeters)
        {
            if(targetLocation != null)
            {
                float distance = loc.distanceTo(targetLocation);
                Log.e("GpsService ","Location latitude +"+loc.getLatitude()+"longitude "+loc.getLongitude());
                if(distance < 5.0)
                    Toast.makeText(getBaseContext(), "You have reached the target location", Toast.LENGTH_LONG).show();

            }
        }

    }

public void setTargetLocation (Location _location){
    targetLocation = _location;
}


/**
 * Class for clients to access. Because we know this service always runs in
 * the same process as its clients, we don't need to deal with IPC.
 */
public class LocalBinder extends Binder {
        GpsService getService() {
                return GpsService.this;
        }
}

private final IBinder mBinder = new LocalBinder();

@Override
public void onDestroy() {
    if(lm != null)
        lm.removeUpdates(locationListener);
    super.onDestroy();
}

//Setting up for test case
public void setUpProvider(String provider){

    lm = (LocationManager) getSystemService(Context.LOCATION_SERVICE);

    locationListener = new MyLocationListener();

    lm.requestLocationUpdates(provider, 
                    minTimeMillis, 
                    minDistanceMeters,
                    locationListener);

}

Now here is my TestCase

открытый класс MockLocationTest расширяет ServiceTestCase {

private LocationManager locationManager = null;
private static final String MOCK_GPS_PROVIDER = "MOCK_GPS_PROVIDER";
private List<String> data = new ArrayList<String>();

public MockLocationTest(Class<GpsService> serviceClass) {
    super(serviceClass);

}

public MockLocationTest() {
    super(GpsService.class);

}


 @Override
    protected void setupService() {

        super.setupService();
        System.out.println("Service Set Up");
        Intent intent = new Intent(getContext(),GpsService.class);
        startService(intent);
        assertNotNull("The Service should not be null",getService());
        System.out.println("Service Started");
    }


    @Override
    protected void setUp() throws Exception {
        super.setUp();



    }



    @MediumTest
    public void testBindable() {

        Intent startIntent = new Intent();
        startIntent.setClass(getContext(), GpsService.class);
        IBinder service =  bindService(startIntent);
        assertNotNull("Bound to service ",service);
        getService().setUpProvider(MOCK_GPS_PROVIDER);

        Location demo = new Location(MOCK_GPS_PROVIDER);
        demo.setLatitude(22.579937);
        demo.setLongitude(88.486805);
        getService().setTargetLocation(demo);

        System.out.println("Test Bindable");
    }






    @SmallTest
    public void testMockData(){
        locationManager = (LocationManager) getContext().getSystemService((Context.LOCATION_SERVICE));

        locationManager.setTestProviderEnabled(MOCK_GPS_PROVIDER, true);
        Location location = new Location(MOCK_GPS_PROVIDER);
        location.setLatitude(22.579937);
        location.setLongitude(88.486805);

        location.setTime(System.currentTimeMillis());

        // show debug message in log


        // provide the new location

        locationManager.setTestProviderLocation(MOCK_GPS_PROVIDER, location);//send mock data


    }

    @Override
    protected void tearDown() throws Exception {

        super.tearDown();
    }

}

К сожалению, я не вижу никаких журналов в обратном вызове onLocationChange в сервисе. Тестовый сценарий успешно выполнен. Я добавил следующее в манифест моей службы и testservice

 <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
     <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.ACCESS_MOCK_LOCATION"/>

Can anybody help me here

Я также пытался поместить это в одну функцию

@ LargeTest public void testBindable () {

        Intent startIntent = new Intent();
        startIntent.setClass(getContext(), GpsService.class);
        IBinder service =  bindService(startIntent);
        assertNotNull("Bound to service ",service);
        LocationManager locationManager = (LocationManager) getContext().getSystemService(Context.LOCATION_SERVICE);
        locationManager.addTestProvider(MOCK_GPS_PROVIDER, false, false,
                false, false, false, false, false, 0, 5);
        locationManager.setTestProviderEnabled(MOCK_GPS_PROVIDER, true);
        getService().setUpProvider(MOCK_GPS_PROVIDER,locationManager);


        Location demo = new Location(MOCK_GPS_PROVIDER);
        demo.setLatitude(22.579937);
        demo.setLongitude(88.486805);
        demo.setTime(System.currentTimeMillis());
        getService().setTargetLocation(demo);

        Location narkeldanga = new Location(MOCK_GPS_PROVIDER);
        narkeldanga.setLatitude(22.578986);
        narkeldanga.setLongitude(88.470154);
        narkeldanga.setTime(System.currentTimeMillis());



        locationManager.setTestProviderLocation(MOCK_GPS_PROVIDER, narkeldanga);

        try {
            Thread.sleep(10000);

            // gracefully handle Thread interruption (important!)
            if(Thread.currentThread().isInterrupted())
                throw new InterruptedException("");
        } catch (InterruptedException e) {

        }

        locationManager.setTestProviderLocation(MOCK_GPS_PROVIDER, demo);

        try {
            Thread.sleep(10000);

            // gracefully handle Thread interruption (important!)
            if(Thread.currentThread().isInterrupted())
                throw new InterruptedException("");
        } catch (InterruptedException e) {

        }

        System.out.println("Test Bindable");
    }

но безрезультатно.

Ответы [ 2 ]

0 голосов
/ 02 октября 2014

Значение MOCK_GPS_PROVIDER не должно быть "flp"?

http://developer.android.com/training/location/location-testing.html#TestData

0 голосов
/ 13 марта 2012

Это проблема, с которой я и другие сталкивались в тестах jUnit.А именно, testBindable () будет выполняться в одном потоке, в то время как ваша служба работает в другом.В результате служба определения местоположения все еще настраивается и даже не думала об использовании ваших обратных вызовов, когда тест завершается, а jUnit очищает все из памяти.Я все еще ищу хороший рецепт для структурирования такого теста, но я могу предложить несколько вещей, которые вы могли бы попробовать.Самое простое - просто включить в тест sleep (), чтобы дать время для обработки в других потоках.Например:

public void testBindable() throws Exception {

    Intent startIntent = new Intent();
    startIntent.setClass(getContext(), GpsService.class);
    IBinder service =  bindService(startIntent);
    assertNotNull("Bound to service ",service);
    getService().setUpProvider(MOCK_GPS_PROVIDER);

    Location demo = new Location(MOCK_GPS_PROVIDER);
    demo.setLatitude(22.579937);
    demo.setLongitude(88.486805);
    getService().setTargetLocation(demo);

    TimeUnit.SECONDS.sleep(5);

    System.out.println("Test Bindable");
}

Этот подход не идеален по ряду причин.5 секунд (или что-то, что вы вставили) может не хватить иногда или слишком много времени в других случаях.

Кроме того, вы можете использовать защелки или другие механизмы, чтобы определить, когда ваши обратные вызовы были выполнены.Однако такой подход усложняет ваш код защелками (или вы можете использовать блокировки мьютекса), которые используются только тестом и в идеале не должны быть частью реального тестируемого приложения.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...