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回调中看到任何日志。测试用例成功运行。 我在服务和测试服务的清单
中添加了以下内容 <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");
}
但无济于事。
答案 0 :(得分:0)
这是我和其他人在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秒(或任何你放入的东西)有时可能不够或在其他情况下时间太长。
或者,您可以使用锁存器或其他机制来检测回调何时执行。但是,这种方法使您的代码与使用仅仅由测试使用的锁存器(或者您可以使用互斥锁)相混淆,理想情况下不应该是测试中的实际应用程序的一部分。
答案 1 :(得分:0)
MOCK_GPS_PROVIDER的值不应该是“flp”?
http://developer.android.com/training/location/location-testing.html#TestData