1 package org.robolectric.android.controller; 2 3 import static org.assertj.core.api.Assertions.assertThat; 4 import static org.robolectric.Shadows.shadowOf; 5 6 import android.app.IntentService; 7 import android.content.ComponentName; 8 import android.content.Intent; 9 import android.os.Handler; 10 import android.os.IBinder; 11 import android.os.Looper; 12 import java.util.ArrayList; 13 import java.util.List; 14 import org.junit.Before; 15 import org.junit.Test; 16 import org.junit.runner.RunWith; 17 import org.robolectric.Robolectric; 18 import org.robolectric.RobolectricTestRunner; 19 import org.robolectric.shadows.ShadowLooper; 20 21 @RunWith(RobolectricTestRunner.class) 22 public class IntentServiceControllerTest { 23 private static final List<String> transcript = new ArrayList<>(); 24 private final ComponentName componentName = new ComponentName("org.robolectric", MyService.class.getName()); 25 private final IntentServiceController<MyService> controller = Robolectric.buildIntentService(MyService.class, new Intent()); 26 27 @Before 28 public void setUp() throws Exception { 29 transcript.clear(); 30 } 31 32 @Test 33 public void onBindShouldSetIntent() throws Exception { 34 MyService myService = controller.create().bind().get(); 35 assertThat(myService.boundIntent).isNotNull(); 36 assertThat(myService.boundIntent.getComponent()).isEqualTo(componentName); 37 } 38 39 @Test 40 public void onStartCommandShouldSetIntent() throws Exception { 41 MyService myService = controller.create().startCommand(3, 4).get(); 42 assertThat(myService.startIntent).isNotNull(); 43 assertThat(myService.startIntent.getComponent()).isEqualTo(componentName); 44 } 45 46 @Test 47 public void onBindShouldSetIntentComponentWithCustomIntentWithoutComponentSet() throws Exception { 48 MyService myService = Robolectric.buildIntentService(MyService.class, new Intent(Intent.ACTION_VIEW)).bind().get(); 49 assertThat(myService.boundIntent.getAction()).isEqualTo(Intent.ACTION_VIEW); 50 assertThat(myService.boundIntent.getComponent()).isEqualTo(componentName); 51 } 52 53 @Test 54 public void shouldSetIntentForGivenServiceInstance() throws Exception { 55 IntentServiceController<MyService> intentServiceController = IntentServiceController.of(new MyService(""), null).bind(); 56 assertThat(intentServiceController.get().boundIntent).isNotNull(); 57 } 58 59 @Test 60 public void whenLooperIsNotPaused_shouldCreateWithMainLooperPaused() throws Exception { 61 ShadowLooper.unPauseMainLooper(); 62 controller.create(); 63 assertThat(shadowOf(Looper.getMainLooper()).isPaused()).isFalse(); 64 assertThat(transcript).contains("finishedOnCreate", "onCreate"); 65 } 66 67 @Test 68 public void whenLooperIsAlreadyPaused_shouldCreateWithMainLooperPaused() throws Exception { 69 ShadowLooper.pauseMainLooper(); 70 controller.create(); 71 assertThat(shadowOf(Looper.getMainLooper()).isPaused()).isTrue(); 72 assertThat(transcript).contains("finishedOnCreate"); 73 74 ShadowLooper.unPauseMainLooper(); 75 assertThat(transcript).contains("onCreate"); 76 } 77 78 @Test 79 public void unbind_callsUnbindWhilePaused() { 80 controller.create().bind().unbind(); 81 assertThat(transcript).contains("finishedOnUnbind", "onUnbind"); 82 } 83 84 @Test 85 public void rebind_callsRebindWhilePaused() { 86 controller.create().bind().unbind().bind().rebind(); 87 assertThat(transcript).contains("finishedOnRebind", "onRebind"); 88 } 89 90 @Test 91 public void destroy_callsOnDestroyWhilePaused() { 92 controller.create().destroy(); 93 assertThat(transcript).contains("finishedOnDestroy", "onDestroy"); 94 } 95 96 @Test 97 public void bind_callsOnBindWhilePaused() { 98 controller.create().bind(); 99 assertThat(transcript).contains("finishedOnBind", "onBind"); 100 } 101 102 @Test 103 public void startCommand_callsOnHandleIntentWhilePaused() { 104 controller.create().startCommand(1, 2); 105 assertThat(transcript).contains("finishedOnHandleIntent", "onHandleIntent"); 106 } 107 108 public static class MyService extends IntentService { 109 private Handler handler = new Handler(Looper.getMainLooper()); 110 111 public Intent boundIntent; 112 113 public Intent reboundIntent; 114 public Intent startIntent; 115 116 public Intent unboundIntent; 117 118 public MyService(String name) { 119 super(name); 120 } 121 122 @Override 123 public IBinder onBind(Intent intent) { 124 boundIntent = intent; 125 transcribeWhilePaused("onBind"); 126 transcript.add("finishedOnBind"); 127 return null; 128 } 129 130 @Override 131 protected void onHandleIntent(Intent intent) { 132 startIntent = intent; 133 transcribeWhilePaused("onHandleIntent"); 134 transcript.add("finishedOnHandleIntent"); 135 } 136 137 @Override 138 public void onCreate() { 139 super.onCreate(); 140 transcribeWhilePaused("onCreate"); 141 transcript.add("finishedOnCreate"); 142 } 143 144 @Override 145 public void onDestroy() { 146 super.onDestroy(); 147 transcribeWhilePaused("onDestroy"); 148 transcript.add("finishedOnDestroy"); 149 } 150 151 @Override 152 public void onRebind(Intent intent) { 153 reboundIntent = intent; 154 transcribeWhilePaused("onRebind"); 155 transcript.add("finishedOnRebind"); 156 } 157 158 @Override 159 public boolean onUnbind(Intent intent) { 160 unboundIntent = intent; 161 transcribeWhilePaused("onUnbind"); 162 transcript.add("finishedOnUnbind"); 163 return false; 164 } 165 166 private void transcribeWhilePaused(final String event) { 167 runOnUiThread(new Runnable() { 168 @Override public void run() { 169 transcript.add(event); 170 } 171 }); 172 } 173 174 private void runOnUiThread(Runnable action) { 175 // This is meant to emulate the behavior of Activity.runOnUiThread(); 176 shadowOf(handler.getLooper()).getScheduler().post(action); 177 } 178 } 179 } 180