ServiceTestCase.java revision 7aee61f5a96e94e158bf5ad3d8e192c4d4f7eff6
19066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/* 29066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Copyright (C) 2008 The Android Open Source Project 39066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 49066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License"); 59066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * you may not use this file except in compliance with the License. 69066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * You may obtain a copy of the License at 79066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 89066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 99066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Unless required by applicable law or agreed to in writing, software 119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, 129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * See the License for the specific language governing permissions and 149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * limitations under the License. 159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpackage android.test; 189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.app.Application; 209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.app.Service; 219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.ComponentName; 229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.Context; 239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.Intent; 249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.IBinder; 259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.RemoteException; 269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.test.mock.MockApplication; 279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.lang.reflect.Field; 299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.util.Random; 309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/** 329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * This test case provides a framework in which you can test Service classes in 339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * a controlled environment. It provides basic support for the lifecycle of a 347d433aabb731a790fc8d06d260c826751215113fJoe Malin * Service, and hooks with which you can inject various dependencies and control 359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * the environment in which your Service is tested. 369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p><b>Lifecycle Support.</b> 387d433aabb731a790fc8d06d260c826751215113fJoe Malin * A Service is accessed with a specific sequence of 397aee61f5a96e94e158bf5ad3d8e192c4d4f7eff6Scott Main * calls, as described in the 407aee61f5a96e94e158bf5ad3d8e192c4d4f7eff6Scott Main * <a href="http://developer.android.com/guide/topics/fundamentals/services.html">Services</a> 417aee61f5a96e94e158bf5ad3d8e192c4d4f7eff6Scott Main * document. In order to support the lifecycle of a Service, 427d433aabb731a790fc8d06d260c826751215113fJoe Malin * <code>ServiceTestCase</code> enforces this protocol: 439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 447d433aabb731a790fc8d06d260c826751215113fJoe Malin * <ul> 457d433aabb731a790fc8d06d260c826751215113fJoe Malin * <li> 467d433aabb731a790fc8d06d260c826751215113fJoe Malin * The {@link #setUp()} method is called before each test method. The base implementation 477d433aabb731a790fc8d06d260c826751215113fJoe Malin * gets the system context. If you override <code>setUp()</code>, you must call 487d433aabb731a790fc8d06d260c826751215113fJoe Malin * <code>super.setUp()</code> as the first statement in your override. 497d433aabb731a790fc8d06d260c826751215113fJoe Malin * </li> 507d433aabb731a790fc8d06d260c826751215113fJoe Malin * <li> 517d433aabb731a790fc8d06d260c826751215113fJoe Malin * The test case waits to call {@link android.app.Service#onCreate()} until one of your 527d433aabb731a790fc8d06d260c826751215113fJoe Malin * test methods calls {@link #startService} or {@link #bindService}. This gives you an 537d433aabb731a790fc8d06d260c826751215113fJoe Malin * opportunity to set up or adjust any additional framework or test logic before you test 547d433aabb731a790fc8d06d260c826751215113fJoe Malin * the running service. 557d433aabb731a790fc8d06d260c826751215113fJoe Malin * </li> 567d433aabb731a790fc8d06d260c826751215113fJoe Malin * <li> 577d433aabb731a790fc8d06d260c826751215113fJoe Malin * When one of your test methods calls {@link #startService ServiceTestCase.startService()} 587d433aabb731a790fc8d06d260c826751215113fJoe Malin * or {@link #bindService ServiceTestCase.bindService()}, the test case calls 597d433aabb731a790fc8d06d260c826751215113fJoe Malin * {@link android.app.Service#onCreate() Service.onCreate()} and then calls either 607d433aabb731a790fc8d06d260c826751215113fJoe Malin * {@link android.app.Service#startService(Intent) Service.startService(Intent)} or 617d433aabb731a790fc8d06d260c826751215113fJoe Malin * {@link android.app.Service#bindService(Intent, ServiceConnection, int) 627d433aabb731a790fc8d06d260c826751215113fJoe Malin * Service.bindService(Intent, ServiceConnection, int)}, as appropriate. It also stores 637d433aabb731a790fc8d06d260c826751215113fJoe Malin * values needed to track and support the lifecycle. 647d433aabb731a790fc8d06d260c826751215113fJoe Malin * </li> 657d433aabb731a790fc8d06d260c826751215113fJoe Malin * <li> 667d433aabb731a790fc8d06d260c826751215113fJoe Malin * After each test method finishes, the test case calls the {@link #tearDown} method. This 677d433aabb731a790fc8d06d260c826751215113fJoe Malin * method stops and destroys the service with the appropriate calls, depending on how the 687d433aabb731a790fc8d06d260c826751215113fJoe Malin * service was started. If you override <code>tearDown()</code>, your must call the 697d433aabb731a790fc8d06d260c826751215113fJoe Malin * <code>super.tearDown()</code> as the last statement in your override. 707d433aabb731a790fc8d06d260c826751215113fJoe Malin * </li> 719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * </ul> 727d433aabb731a790fc8d06d260c826751215113fJoe Malin * 737d433aabb731a790fc8d06d260c826751215113fJoe Malin * <p> 747d433aabb731a790fc8d06d260c826751215113fJoe Malin * <strong>Dependency Injection.</strong> 757d433aabb731a790fc8d06d260c826751215113fJoe Malin * A service has two inherent dependencies, its {@link android.content.Context Context} and its 767d433aabb731a790fc8d06d260c826751215113fJoe Malin * associated {@link android.app.Application Application}. The ServiceTestCase framework 777d433aabb731a790fc8d06d260c826751215113fJoe Malin * allows you to inject modified, mock, or isolated replacements for these dependencies, and 787d433aabb731a790fc8d06d260c826751215113fJoe Malin * thus perform unit tests with controlled dependencies in an isolated environment. 797d433aabb731a790fc8d06d260c826751215113fJoe Malin * </p> 807d433aabb731a790fc8d06d260c826751215113fJoe Malin * <p> 817d433aabb731a790fc8d06d260c826751215113fJoe Malin * By default, the test case is injected with a full system context and a generic 827d433aabb731a790fc8d06d260c826751215113fJoe Malin * {@link android.test.mock.MockApplication MockApplication} object. You can inject 837d433aabb731a790fc8d06d260c826751215113fJoe Malin * alternatives to either of these by invoking 847d433aabb731a790fc8d06d260c826751215113fJoe Malin * {@link AndroidTestCase#setContext(Context) setContext()} or 857d433aabb731a790fc8d06d260c826751215113fJoe Malin * {@link #setApplication setApplication()}. You must do this <em>before</em> calling 867d433aabb731a790fc8d06d260c826751215113fJoe Malin * startService() or bindService(). The test framework provides a 877d433aabb731a790fc8d06d260c826751215113fJoe Malin * number of alternatives for Context, including 887d433aabb731a790fc8d06d260c826751215113fJoe Malin * {link android.test.mock.MockContext MockContext}, 897d433aabb731a790fc8d06d260c826751215113fJoe Malin * {@link android.test.RenamingDelegatingContext RenamingDelegatingContext}, 907d433aabb731a790fc8d06d260c826751215113fJoe Malin * {@link android.content.ContextWrapper ContextWrapper}, and 917d433aabb731a790fc8d06d260c826751215113fJoe Malin * {@link android.test.IsolatedContext}. 929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpublic abstract class ServiceTestCase<T extends Service> extends AndroidTestCase { 949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Class<T> mServiceClass; 969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private Context mSystemContext; 989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private Application mApplication; 999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1007d433aabb731a790fc8d06d260c826751215113fJoe Malin /** 1017d433aabb731a790fc8d06d260c826751215113fJoe Malin * Constructor 1027d433aabb731a790fc8d06d260c826751215113fJoe Malin * @param serviceClass The type of the service under test. 1037d433aabb731a790fc8d06d260c826751215113fJoe Malin */ 1049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public ServiceTestCase(Class<T> serviceClass) { 1059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mServiceClass = serviceClass; 1069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private T mService; 1099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private boolean mServiceAttached = false; 1109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private boolean mServiceCreated = false; 1119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private boolean mServiceStarted = false; 1129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private boolean mServiceBound = false; 1139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private Intent mServiceIntent = null; 1149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private int mServiceId; 1159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1177d433aabb731a790fc8d06d260c826751215113fJoe Malin * @return An instance of the service under test. This instance is created automatically when 1187d433aabb731a790fc8d06d260c826751215113fJoe Malin * a test calls {@link #startService} or {@link #bindService}. 1199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public T getService() { 1219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mService; 1229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1257d433aabb731a790fc8d06d260c826751215113fJoe Malin * Gets the current system context and stores it. 1267d433aabb731a790fc8d06d260c826751215113fJoe Malin * 1277d433aabb731a790fc8d06d260c826751215113fJoe Malin * Extend this method to do your own test initialization. If you do so, you 1287d433aabb731a790fc8d06d260c826751215113fJoe Malin * must call <code>super.setUp()</code> as the first statement in your override. The method is 1297d433aabb731a790fc8d06d260c826751215113fJoe Malin * called before each test method is executed. 1309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 1329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project protected void setUp() throws Exception { 1339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project super.setUp(); 1347d433aabb731a790fc8d06d260c826751215113fJoe Malin 1359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // get the real context, before the individual tests have a chance to muck with it 1369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mSystemContext = getContext(); 1379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1397d433aabb731a790fc8d06d260c826751215113fJoe Malin 1409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1417d433aabb731a790fc8d06d260c826751215113fJoe Malin * Creates the service under test and attaches all injected dependencies 1427d433aabb731a790fc8d06d260c826751215113fJoe Malin * (Context, Application) to it. This is called automatically by {@link #startService} or 1437d433aabb731a790fc8d06d260c826751215113fJoe Malin * by {@link #bindService}. 1447d433aabb731a790fc8d06d260c826751215113fJoe Malin * If you need to call {@link AndroidTestCase#setContext(Context) setContext()} or 1457d433aabb731a790fc8d06d260c826751215113fJoe Malin * {@link #setApplication setApplication()}, do so before calling this method. 1469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project protected void setupService() { 1489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mService = null; 1499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 1509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mService = mServiceClass.newInstance(); 1519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (Exception e) { 1529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project assertNotNull(mService); 1539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (getApplication() == null) { 1559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project setApplication(new MockApplication()); 1569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mService.attach( 1589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project getContext(), 1599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project null, // ActivityThread not actually used in Service 1609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mServiceClass.getName(), 1619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project null, // token not needed when not talking with the activity manager 1629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project getApplication(), 1639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project null // mocked services don't talk with the activity manager 1649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ); 1657d433aabb731a790fc8d06d260c826751215113fJoe Malin 1669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project assertNotNull(mService); 1677d433aabb731a790fc8d06d260c826751215113fJoe Malin 1689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mServiceId = new Random().nextInt(); 1699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mServiceAttached = true; 1709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1717d433aabb731a790fc8d06d260c826751215113fJoe Malin 1729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1737d433aabb731a790fc8d06d260c826751215113fJoe Malin * Starts the service under test, in the same way as if it were started by 1747d433aabb731a790fc8d06d260c826751215113fJoe Malin * {@link android.content.Context#startService(Intent) Context.startService(Intent)} with 1757d433aabb731a790fc8d06d260c826751215113fJoe Malin * an {@link android.content.Intent} that identifies a service. 1767d433aabb731a790fc8d06d260c826751215113fJoe Malin * If you use this method to start the service, it is automatically stopped by 1777d433aabb731a790fc8d06d260c826751215113fJoe Malin * {@link #tearDown}. 1787d433aabb731a790fc8d06d260c826751215113fJoe Malin * 1797d433aabb731a790fc8d06d260c826751215113fJoe Malin * @param intent An Intent that identifies a service, of the same form as the Intent passed to 1807d433aabb731a790fc8d06d260c826751215113fJoe Malin * {@link android.content.Context#startService(Intent) Context.startService(Intent)}. 1819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project protected void startService(Intent intent) { 1839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!mServiceAttached) { 1849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project setupService(); 1859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project assertNotNull(mService); 1877d433aabb731a790fc8d06d260c826751215113fJoe Malin 1889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!mServiceCreated) { 1899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mService.onCreate(); 1909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mServiceCreated = true; 1919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 19271be4b5ed994030171fb3bd3f08fbc8c43c47567Evan Millar mService.onStartCommand(intent, 0, mServiceId); 1937d433aabb731a790fc8d06d260c826751215113fJoe Malin 1949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mServiceStarted = true; 1959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1977d433aabb731a790fc8d06d260c826751215113fJoe Malin /** 1987d433aabb731a790fc8d06d260c826751215113fJoe Malin * <p> 1997d433aabb731a790fc8d06d260c826751215113fJoe Malin * Starts the service under test, in the same way as if it were started by 2007d433aabb731a790fc8d06d260c826751215113fJoe Malin * {@link android.content.Context#bindService(Intent, ServiceConnection, int) 2017d433aabb731a790fc8d06d260c826751215113fJoe Malin * Context.bindService(Intent, ServiceConnection, flags)} with an 2027d433aabb731a790fc8d06d260c826751215113fJoe Malin * {@link android.content.Intent} that identifies a service. 2037d433aabb731a790fc8d06d260c826751215113fJoe Malin * </p> 2047d433aabb731a790fc8d06d260c826751215113fJoe Malin * <p> 2057d433aabb731a790fc8d06d260c826751215113fJoe Malin * Notice that the parameters are different. You do not provide a 2067d433aabb731a790fc8d06d260c826751215113fJoe Malin * {@link android.content.ServiceConnection} object or the flags parameter. Instead, 2077d433aabb731a790fc8d06d260c826751215113fJoe Malin * you only provide the Intent. The method returns an object whose type is a 2087d433aabb731a790fc8d06d260c826751215113fJoe Malin * subclass of {@link android.os.IBinder}, or null if the method fails. An IBinder 2097d433aabb731a790fc8d06d260c826751215113fJoe Malin * object refers to a communication channel between the application and 2107d433aabb731a790fc8d06d260c826751215113fJoe Malin * the service. The flag is assumed to be {@link android.content.Context#BIND_AUTO_CREATE}. 2117d433aabb731a790fc8d06d260c826751215113fJoe Malin * </p> 2127d433aabb731a790fc8d06d260c826751215113fJoe Malin * <p> 2137d433aabb731a790fc8d06d260c826751215113fJoe Malin * See <a href="{@docRoot}guide/developing/tools/aidl.html">Designing a Remote Interface 2147d433aabb731a790fc8d06d260c826751215113fJoe Malin * Using AIDL</a> for more information about the communication channel object returned 2157d433aabb731a790fc8d06d260c826751215113fJoe Malin * by this method. 2167d433aabb731a790fc8d06d260c826751215113fJoe Malin * </p> 2177d433aabb731a790fc8d06d260c826751215113fJoe Malin * Note: To be able to use bindService in a test, the service must implement getService() 2187d433aabb731a790fc8d06d260c826751215113fJoe Malin * method. An example of this is in the ApiDemos sample application, in the 2197d433aabb731a790fc8d06d260c826751215113fJoe Malin * LocalService demo. 2207d433aabb731a790fc8d06d260c826751215113fJoe Malin * 2217d433aabb731a790fc8d06d260c826751215113fJoe Malin * @param intent An Intent object of the form expected by 2227d433aabb731a790fc8d06d260c826751215113fJoe Malin * {@link android.content.Context#bindService}. 2237d433aabb731a790fc8d06d260c826751215113fJoe Malin * 2247d433aabb731a790fc8d06d260c826751215113fJoe Malin * @return An object whose type is a subclass of IBinder, for making further calls into 2257d433aabb731a790fc8d06d260c826751215113fJoe Malin * the service. 2269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 2279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project protected IBinder bindService(Intent intent) { 2289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!mServiceAttached) { 2299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project setupService(); 2309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project assertNotNull(mService); 2327d433aabb731a790fc8d06d260c826751215113fJoe Malin 2339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!mServiceCreated) { 2349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mService.onCreate(); 2359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mServiceCreated = true; 2369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // no extras are expected by unbind 2389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mServiceIntent = intent.cloneFilter(); 2399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project IBinder result = mService.onBind(intent); 2407d433aabb731a790fc8d06d260c826751215113fJoe Malin 2419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mServiceBound = true; 2429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return result; 2439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2447d433aabb731a790fc8d06d260c826751215113fJoe Malin 2459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 2467d433aabb731a790fc8d06d260c826751215113fJoe Malin * Makes the necessary calls to stop (or unbind) the service under test, and 2477d433aabb731a790fc8d06d260c826751215113fJoe Malin * calls onDestroy(). Ordinarily this is called automatically (by {@link #tearDown}, but 2487d433aabb731a790fc8d06d260c826751215113fJoe Malin * you can call it directly from your test in order to check for proper shutdown behavior. 2499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 2509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project protected void shutdownService() { 2519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mServiceStarted) { 2529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mService.stopSelf(); 2539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mServiceStarted = false; 2549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (mServiceBound) { 2559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mService.onUnbind(mServiceIntent); 2569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mServiceBound = false; 2579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mServiceCreated) { 2599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mService.onDestroy(); 2609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2627d433aabb731a790fc8d06d260c826751215113fJoe Malin 2639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 2647d433aabb731a790fc8d06d260c826751215113fJoe Malin * <p> 2657d433aabb731a790fc8d06d260c826751215113fJoe Malin * Shuts down the service under test. Ensures all resources are cleaned up and 2667d433aabb731a790fc8d06d260c826751215113fJoe Malin * garbage collected before moving on to the next test. This method is called after each 2677d433aabb731a790fc8d06d260c826751215113fJoe Malin * test method. 2687d433aabb731a790fc8d06d260c826751215113fJoe Malin * </p> 2697d433aabb731a790fc8d06d260c826751215113fJoe Malin * <p> 2707d433aabb731a790fc8d06d260c826751215113fJoe Malin * Subclasses that override this method must call <code>super.tearDown()</code> as their 2717d433aabb731a790fc8d06d260c826751215113fJoe Malin * last statement. 2727d433aabb731a790fc8d06d260c826751215113fJoe Malin * </p> 2737d433aabb731a790fc8d06d260c826751215113fJoe Malin * 2749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @throws Exception 2759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 2769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 2779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project protected void tearDown() throws Exception { 2789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project shutdownService(); 2799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mService = null; 2809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2817d433aabb731a790fc8d06d260c826751215113fJoe Malin // Scrub out members - protects against memory leaks in the case where someone 2829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // creates a non-static inner class (thus referencing the test case) and gives it to 2839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // someone else to hold onto 2849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project scrubClass(ServiceTestCase.class); 2859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project super.tearDown(); 2879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2887d433aabb731a790fc8d06d260c826751215113fJoe Malin 2899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 2907d433aabb731a790fc8d06d260c826751215113fJoe Malin * Sets the application that is used during the test. If you do not call this method, 2917d433aabb731a790fc8d06d260c826751215113fJoe Malin * a new {@link android.test.mock.MockApplication MockApplication} object is used. 2927d433aabb731a790fc8d06d260c826751215113fJoe Malin * 2937d433aabb731a790fc8d06d260c826751215113fJoe Malin * @param application The Application object that is used by the service under test. 2947d433aabb731a790fc8d06d260c826751215113fJoe Malin * 2957d433aabb731a790fc8d06d260c826751215113fJoe Malin * @see #getApplication() 2969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 2979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void setApplication(Application application) { 2989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mApplication = application; 2999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 3027d433aabb731a790fc8d06d260c826751215113fJoe Malin * Returns the Application object in use by the service under test. 3037d433aabb731a790fc8d06d260c826751215113fJoe Malin * 3047d433aabb731a790fc8d06d260c826751215113fJoe Malin * @return The application object. 3057d433aabb731a790fc8d06d260c826751215113fJoe Malin * 3069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @see #setApplication 3079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 3089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public Application getApplication() { 3099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mApplication; 3109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3117d433aabb731a790fc8d06d260c826751215113fJoe Malin 3129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 3137d433aabb731a790fc8d06d260c826751215113fJoe Malin * Returns the real system context that is saved by {@link #setUp()}. Use it to create 3147d433aabb731a790fc8d06d260c826751215113fJoe Malin * mock or other types of context objects for the service under test. 3157d433aabb731a790fc8d06d260c826751215113fJoe Malin * 3167d433aabb731a790fc8d06d260c826751215113fJoe Malin * @return A normal system context. 3179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 3189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public Context getSystemContext() { 3199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mSystemContext; 3209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3227d433aabb731a790fc8d06d260c826751215113fJoe Malin /** 3237d433aabb731a790fc8d06d260c826751215113fJoe Malin * Tests that {@link #setupService()} runs correctly and issues an 3247d433aabb731a790fc8d06d260c826751215113fJoe Malin * {@link junit.framework.Assert#assertNotNull(String, Object)} if it does. 3257d433aabb731a790fc8d06d260c826751215113fJoe Malin * You can override this test method if you wish. 3267d433aabb731a790fc8d06d260c826751215113fJoe Malin * 3277d433aabb731a790fc8d06d260c826751215113fJoe Malin * @throws Exception 3287d433aabb731a790fc8d06d260c826751215113fJoe Malin */ 3299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void testServiceTestCaseSetUpProperly() throws Exception { 3309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project setupService(); 3319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project assertNotNull("service should be launched successfully", mService); 3329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 334