xref: /aosp_15_r20/external/dagger2/javatests/dagger/hilt/android/InjectionTest.java (revision f585d8a307d0621d6060bd7e80091fdcbf94fe27)
1*f585d8a3SJacky Wang /*
2*f585d8a3SJacky Wang  * Copyright (C) 2020 The Dagger Authors.
3*f585d8a3SJacky Wang  *
4*f585d8a3SJacky Wang  * Licensed under the Apache License, Version 2.0 (the "License");
5*f585d8a3SJacky Wang  * you may not use this file except in compliance with the License.
6*f585d8a3SJacky Wang  * You may obtain a copy of the License at
7*f585d8a3SJacky Wang  *
8*f585d8a3SJacky Wang  * http://www.apache.org/licenses/LICENSE-2.0
9*f585d8a3SJacky Wang  *
10*f585d8a3SJacky Wang  * Unless required by applicable law or agreed to in writing, software
11*f585d8a3SJacky Wang  * distributed under the License is distributed on an "AS IS" BASIS,
12*f585d8a3SJacky Wang  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*f585d8a3SJacky Wang  * See the License for the specific language governing permissions and
14*f585d8a3SJacky Wang  * limitations under the License.
15*f585d8a3SJacky Wang  */
16*f585d8a3SJacky Wang 
17*f585d8a3SJacky Wang package dagger.hilt.android;
18*f585d8a3SJacky Wang 
19*f585d8a3SJacky Wang import static androidx.test.core.app.ApplicationProvider.getApplicationContext;
20*f585d8a3SJacky Wang import static com.google.common.truth.Truth.assertThat;
21*f585d8a3SJacky Wang import static java.lang.annotation.RetentionPolicy.RUNTIME;
22*f585d8a3SJacky Wang import static org.junit.Assert.fail;
23*f585d8a3SJacky Wang 
24*f585d8a3SJacky Wang import android.annotation.TargetApi;
25*f585d8a3SJacky Wang import android.app.Activity;
26*f585d8a3SJacky Wang import android.app.IntentService;
27*f585d8a3SJacky Wang import android.app.Service;
28*f585d8a3SJacky Wang import android.content.BroadcastReceiver;
29*f585d8a3SJacky Wang import android.content.Context;
30*f585d8a3SJacky Wang import android.content.Intent;
31*f585d8a3SJacky Wang import android.os.Build;
32*f585d8a3SJacky Wang import android.os.Bundle;
33*f585d8a3SJacky Wang import android.os.IBinder;
34*f585d8a3SJacky Wang import androidx.fragment.app.Fragment;
35*f585d8a3SJacky Wang import androidx.fragment.app.FragmentActivity;
36*f585d8a3SJacky Wang import android.util.AttributeSet;
37*f585d8a3SJacky Wang import android.widget.LinearLayout;
38*f585d8a3SJacky Wang import androidx.test.ext.junit.runners.AndroidJUnit4;
39*f585d8a3SJacky Wang import dagger.Module;
40*f585d8a3SJacky Wang import dagger.Provides;
41*f585d8a3SJacky Wang import dagger.hilt.InstallIn;
42*f585d8a3SJacky Wang import dagger.hilt.android.components.ActivityComponent;
43*f585d8a3SJacky Wang import dagger.hilt.android.components.FragmentComponent;
44*f585d8a3SJacky Wang import dagger.hilt.android.components.ServiceComponent;
45*f585d8a3SJacky Wang import dagger.hilt.android.testing.HiltAndroidRule;
46*f585d8a3SJacky Wang import dagger.hilt.android.testing.HiltAndroidTest;
47*f585d8a3SJacky Wang import dagger.hilt.android.testing.HiltTestApplication;
48*f585d8a3SJacky Wang import dagger.hilt.components.SingletonComponent;
49*f585d8a3SJacky Wang import java.lang.annotation.ElementType;
50*f585d8a3SJacky Wang import java.lang.annotation.Retention;
51*f585d8a3SJacky Wang import java.lang.annotation.Target;
52*f585d8a3SJacky Wang import java.util.concurrent.atomic.AtomicLong;
53*f585d8a3SJacky Wang import javax.inject.Inject;
54*f585d8a3SJacky Wang import javax.inject.Qualifier;
55*f585d8a3SJacky Wang import javax.inject.Singleton;
56*f585d8a3SJacky Wang import org.junit.Before;
57*f585d8a3SJacky Wang import org.junit.Rule;
58*f585d8a3SJacky Wang import org.junit.Test;
59*f585d8a3SJacky Wang import org.junit.runner.RunWith;
60*f585d8a3SJacky Wang import org.robolectric.Robolectric;
61*f585d8a3SJacky Wang import org.robolectric.android.controller.ActivityController;
62*f585d8a3SJacky Wang import org.robolectric.annotation.Config;
63*f585d8a3SJacky Wang 
64*f585d8a3SJacky Wang @HiltAndroidTest
65*f585d8a3SJacky Wang @RunWith(AndroidJUnit4.class)
66*f585d8a3SJacky Wang // Robolectric requires Java9 to run API 29 and above, so use API 28 instead
67*f585d8a3SJacky Wang @Config(sdk = Build.VERSION_CODES.P, application = HiltTestApplication.class)
68*f585d8a3SJacky Wang public final class InjectionTest {
69*f585d8a3SJacky Wang   private static final String APP_BINDING = "APP_BINDING";
70*f585d8a3SJacky Wang   private static final String ACTIVITY_BINDING = "ACTIVIY_BINDING";
71*f585d8a3SJacky Wang   private static final String FRAGMENT_BINDING = "FRAGMENT_BINDING";
72*f585d8a3SJacky Wang   private static final String SERVICE_BINDING = "SERVICE_BINDING";
73*f585d8a3SJacky Wang 
74*f585d8a3SJacky Wang   @Retention(RUNTIME)
75*f585d8a3SJacky Wang   @Qualifier
76*f585d8a3SJacky Wang   @Target({ElementType.METHOD, ElementType.PARAMETER, ElementType.FIELD})
77*f585d8a3SJacky Wang   @interface ApplicationLevel {}
78*f585d8a3SJacky Wang 
79*f585d8a3SJacky Wang   @Retention(RUNTIME)
80*f585d8a3SJacky Wang   @Qualifier
81*f585d8a3SJacky Wang   @Target({ElementType.METHOD, ElementType.PARAMETER, ElementType.FIELD})
82*f585d8a3SJacky Wang   @interface ActivityLevel {}
83*f585d8a3SJacky Wang 
84*f585d8a3SJacky Wang   @Retention(RUNTIME)
85*f585d8a3SJacky Wang   @Qualifier
86*f585d8a3SJacky Wang   @Target({ElementType.METHOD, ElementType.PARAMETER, ElementType.FIELD})
87*f585d8a3SJacky Wang   @interface FragmentLevel {}
88*f585d8a3SJacky Wang 
89*f585d8a3SJacky Wang   @Retention(RUNTIME)
90*f585d8a3SJacky Wang   @Qualifier
91*f585d8a3SJacky Wang   @Target({ElementType.METHOD, ElementType.PARAMETER, ElementType.FIELD})
92*f585d8a3SJacky Wang   @interface ServiceLevel {}
93*f585d8a3SJacky Wang 
94*f585d8a3SJacky Wang   /** Application level bindings */
95*f585d8a3SJacky Wang   @Module
96*f585d8a3SJacky Wang   @InstallIn(SingletonComponent.class)
97*f585d8a3SJacky Wang   static final class AppModule {
98*f585d8a3SJacky Wang     @Provides
99*f585d8a3SJacky Wang     @ApplicationLevel
providesAppBinding()100*f585d8a3SJacky Wang     static String providesAppBinding() {
101*f585d8a3SJacky Wang       return APP_BINDING;
102*f585d8a3SJacky Wang     }
103*f585d8a3SJacky Wang 
104*f585d8a3SJacky Wang     @Provides
105*f585d8a3SJacky Wang     @Singleton
provideCounter()106*f585d8a3SJacky Wang     static AtomicLong provideCounter() {
107*f585d8a3SJacky Wang       return new AtomicLong();
108*f585d8a3SJacky Wang     }
109*f585d8a3SJacky Wang 
110*f585d8a3SJacky Wang     @Provides
provideCount(AtomicLong counter)111*f585d8a3SJacky Wang     static Long provideCount(AtomicLong counter) {
112*f585d8a3SJacky Wang       return counter.incrementAndGet();
113*f585d8a3SJacky Wang     }
114*f585d8a3SJacky Wang   }
115*f585d8a3SJacky Wang 
116*f585d8a3SJacky Wang   /** Activity level bindings */
117*f585d8a3SJacky Wang   @Module
118*f585d8a3SJacky Wang   @InstallIn(ActivityComponent.class)
119*f585d8a3SJacky Wang   static final class ActivityModule {
120*f585d8a3SJacky Wang     @Provides
121*f585d8a3SJacky Wang     @ActivityLevel
providesActivityBinding()122*f585d8a3SJacky Wang     static String providesActivityBinding() {
123*f585d8a3SJacky Wang       return ACTIVITY_BINDING;
124*f585d8a3SJacky Wang     }
125*f585d8a3SJacky Wang   }
126*f585d8a3SJacky Wang 
127*f585d8a3SJacky Wang   /** Fragment level bindings */
128*f585d8a3SJacky Wang   @Module
129*f585d8a3SJacky Wang   @InstallIn(FragmentComponent.class)
130*f585d8a3SJacky Wang   static final class FragmentModule {
131*f585d8a3SJacky Wang     @Provides
132*f585d8a3SJacky Wang     @FragmentLevel
providesFragmentBinding()133*f585d8a3SJacky Wang     static String providesFragmentBinding() {
134*f585d8a3SJacky Wang       return FRAGMENT_BINDING;
135*f585d8a3SJacky Wang     }
136*f585d8a3SJacky Wang   }
137*f585d8a3SJacky Wang 
138*f585d8a3SJacky Wang   /** Service level bindings */
139*f585d8a3SJacky Wang   @Module
140*f585d8a3SJacky Wang   @InstallIn(ServiceComponent.class)
141*f585d8a3SJacky Wang   static final class ServiceModule {
142*f585d8a3SJacky Wang     @Provides
143*f585d8a3SJacky Wang     @ServiceLevel
providesServiceBinding()144*f585d8a3SJacky Wang     static String providesServiceBinding() {
145*f585d8a3SJacky Wang       return SERVICE_BINDING;
146*f585d8a3SJacky Wang     }
147*f585d8a3SJacky Wang   }
148*f585d8a3SJacky Wang 
149*f585d8a3SJacky Wang   /** Hilt Activity */
150*f585d8a3SJacky Wang   @AndroidEntryPoint(FragmentActivity.class)
151*f585d8a3SJacky Wang   public static final class TestActivity extends Hilt_InjectionTest_TestActivity {
152*f585d8a3SJacky Wang     @Inject @ApplicationLevel String appBinding;
153*f585d8a3SJacky Wang     @Inject @ActivityLevel String activityBinding;
154*f585d8a3SJacky Wang     boolean onCreateCalled;
155*f585d8a3SJacky Wang 
156*f585d8a3SJacky Wang     @Override
onCreate(Bundle onSavedInstanceState)157*f585d8a3SJacky Wang     public void onCreate(Bundle onSavedInstanceState) {
158*f585d8a3SJacky Wang       assertThat(appBinding).isNull();
159*f585d8a3SJacky Wang       assertThat(activityBinding).isNull();
160*f585d8a3SJacky Wang 
161*f585d8a3SJacky Wang       super.onCreate(onSavedInstanceState);
162*f585d8a3SJacky Wang 
163*f585d8a3SJacky Wang       assertThat(appBinding).isEqualTo(APP_BINDING);
164*f585d8a3SJacky Wang       assertThat(activityBinding).isEqualTo(ACTIVITY_BINDING);
165*f585d8a3SJacky Wang 
166*f585d8a3SJacky Wang       onCreateCalled = true;
167*f585d8a3SJacky Wang     }
168*f585d8a3SJacky Wang   }
169*f585d8a3SJacky Wang 
170*f585d8a3SJacky Wang   /** Non-Hilt Activity */
171*f585d8a3SJacky Wang   public static final class NonHiltActivity extends FragmentActivity {}
172*f585d8a3SJacky Wang 
173*f585d8a3SJacky Wang   /** Hilt Fragment */
174*f585d8a3SJacky Wang   @AndroidEntryPoint(Fragment.class)
175*f585d8a3SJacky Wang   public static final class TestFragment extends Hilt_InjectionTest_TestFragment {
176*f585d8a3SJacky Wang     @Inject @ApplicationLevel String appBinding;
177*f585d8a3SJacky Wang     @Inject @ActivityLevel String activityBinding;
178*f585d8a3SJacky Wang     @Inject @FragmentLevel String fragmentBinding;
179*f585d8a3SJacky Wang     boolean onAttachContextCalled;
180*f585d8a3SJacky Wang     boolean onAttachActivityCalled;
181*f585d8a3SJacky Wang 
182*f585d8a3SJacky Wang     @Override
onAttach(Context context)183*f585d8a3SJacky Wang     public void onAttach(Context context) {
184*f585d8a3SJacky Wang       preInjectionAssert();
185*f585d8a3SJacky Wang       super.onAttach(context);
186*f585d8a3SJacky Wang       postInjectionAssert();
187*f585d8a3SJacky Wang       onAttachContextCalled = true;
188*f585d8a3SJacky Wang     }
189*f585d8a3SJacky Wang 
190*f585d8a3SJacky Wang     @Override
onAttach(Activity activity)191*f585d8a3SJacky Wang     public void onAttach(Activity activity) {
192*f585d8a3SJacky Wang       preInjectionAssert();
193*f585d8a3SJacky Wang       super.onAttach(activity);
194*f585d8a3SJacky Wang       postInjectionAssert();
195*f585d8a3SJacky Wang       onAttachActivityCalled = true;
196*f585d8a3SJacky Wang     }
197*f585d8a3SJacky Wang 
preInjectionAssert()198*f585d8a3SJacky Wang     private void preInjectionAssert() {
199*f585d8a3SJacky Wang       assertThat(appBinding).isNull();
200*f585d8a3SJacky Wang       assertThat(activityBinding).isNull();
201*f585d8a3SJacky Wang       assertThat(fragmentBinding).isNull();
202*f585d8a3SJacky Wang     }
203*f585d8a3SJacky Wang 
postInjectionAssert()204*f585d8a3SJacky Wang     private void postInjectionAssert() {
205*f585d8a3SJacky Wang       assertThat(appBinding).isEqualTo(APP_BINDING);
206*f585d8a3SJacky Wang       assertThat(activityBinding).isEqualTo(ACTIVITY_BINDING);
207*f585d8a3SJacky Wang       assertThat(fragmentBinding).isEqualTo(FRAGMENT_BINDING);
208*f585d8a3SJacky Wang     }
209*f585d8a3SJacky Wang   }
210*f585d8a3SJacky Wang 
211*f585d8a3SJacky Wang   /** Non-Hilt Fragment */
212*f585d8a3SJacky Wang   public static final class NonHiltFragment extends Fragment {}
213*f585d8a3SJacky Wang 
214*f585d8a3SJacky Wang   /** Hilt extends parameterized fragment. */
215*f585d8a3SJacky Wang   @AndroidEntryPoint(ParameterizedFragment.class)
216*f585d8a3SJacky Wang   public static final class TestParameterizedFragment
217*f585d8a3SJacky Wang       extends Hilt_InjectionTest_TestParameterizedFragment<Integer> {
218*f585d8a3SJacky Wang     @Inject @ApplicationLevel String appBinding;
219*f585d8a3SJacky Wang     @Inject @ActivityLevel String activityBinding;
220*f585d8a3SJacky Wang     @Inject @FragmentLevel String fragmentBinding;
221*f585d8a3SJacky Wang     boolean onAttachContextCalled;
222*f585d8a3SJacky Wang     boolean onAttachActivityCalled;
223*f585d8a3SJacky Wang 
224*f585d8a3SJacky Wang     @Override
onAttach(Context context)225*f585d8a3SJacky Wang     public void onAttach(Context context) {
226*f585d8a3SJacky Wang       preInjectionAssert();
227*f585d8a3SJacky Wang       super.onAttach(context);
228*f585d8a3SJacky Wang       postInjectionAssert();
229*f585d8a3SJacky Wang       onAttachContextCalled = true;
230*f585d8a3SJacky Wang     }
231*f585d8a3SJacky Wang 
232*f585d8a3SJacky Wang     @Override
onAttach(Activity activity)233*f585d8a3SJacky Wang     public void onAttach(Activity activity) {
234*f585d8a3SJacky Wang       preInjectionAssert();
235*f585d8a3SJacky Wang       super.onAttach(activity);
236*f585d8a3SJacky Wang       postInjectionAssert();
237*f585d8a3SJacky Wang       onAttachActivityCalled = true;
238*f585d8a3SJacky Wang     }
239*f585d8a3SJacky Wang 
preInjectionAssert()240*f585d8a3SJacky Wang     private void preInjectionAssert() {
241*f585d8a3SJacky Wang       assertThat(appBinding).isNull();
242*f585d8a3SJacky Wang       assertThat(activityBinding).isNull();
243*f585d8a3SJacky Wang       assertThat(fragmentBinding).isNull();
244*f585d8a3SJacky Wang     }
245*f585d8a3SJacky Wang 
postInjectionAssert()246*f585d8a3SJacky Wang     private void postInjectionAssert() {
247*f585d8a3SJacky Wang       assertThat(appBinding).isEqualTo(APP_BINDING);
248*f585d8a3SJacky Wang       assertThat(activityBinding).isEqualTo(ACTIVITY_BINDING);
249*f585d8a3SJacky Wang       assertThat(fragmentBinding).isEqualTo(FRAGMENT_BINDING);
250*f585d8a3SJacky Wang     }
251*f585d8a3SJacky Wang   }
252*f585d8a3SJacky Wang 
253*f585d8a3SJacky Wang   /** Non-Hilt parameterized fragment */
254*f585d8a3SJacky Wang   public static class ParameterizedFragment<T> extends Fragment {}
255*f585d8a3SJacky Wang 
256*f585d8a3SJacky Wang   /** Hilt View */
257*f585d8a3SJacky Wang   @AndroidEntryPoint(LinearLayout.class)
258*f585d8a3SJacky Wang   public static final class TestView extends Hilt_InjectionTest_TestView {
259*f585d8a3SJacky Wang     @Inject @ApplicationLevel String appBinding;
260*f585d8a3SJacky Wang     @Inject @ActivityLevel String activityBinding;
261*f585d8a3SJacky Wang 
TestView(Context context)262*f585d8a3SJacky Wang     TestView(Context context) {
263*f585d8a3SJacky Wang       super(context);
264*f585d8a3SJacky Wang     }
265*f585d8a3SJacky Wang 
TestView(Context context, AttributeSet attrs)266*f585d8a3SJacky Wang     TestView(Context context, AttributeSet attrs) {
267*f585d8a3SJacky Wang       super(context, attrs);
268*f585d8a3SJacky Wang     }
269*f585d8a3SJacky Wang 
TestView(Context context, AttributeSet attrs, int defStyleAttr)270*f585d8a3SJacky Wang     TestView(Context context, AttributeSet attrs, int defStyleAttr) {
271*f585d8a3SJacky Wang       super(context, attrs, defStyleAttr);
272*f585d8a3SJacky Wang     }
273*f585d8a3SJacky Wang 
274*f585d8a3SJacky Wang     @TargetApi(21)
TestView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes)275*f585d8a3SJacky Wang     TestView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
276*f585d8a3SJacky Wang       super(context, attrs, defStyleAttr, defStyleRes);
277*f585d8a3SJacky Wang     }
278*f585d8a3SJacky Wang   }
279*f585d8a3SJacky Wang 
280*f585d8a3SJacky Wang   /** Hilt View (With Fragment bindings) */
281*f585d8a3SJacky Wang   @WithFragmentBindings
282*f585d8a3SJacky Wang   @AndroidEntryPoint(LinearLayout.class)
283*f585d8a3SJacky Wang   public static final class TestViewWithFragmentBindings
284*f585d8a3SJacky Wang       extends Hilt_InjectionTest_TestViewWithFragmentBindings {
285*f585d8a3SJacky Wang     @Inject @ApplicationLevel String appBinding;
286*f585d8a3SJacky Wang     @Inject @ActivityLevel String activityBinding;
287*f585d8a3SJacky Wang     @Inject @FragmentLevel String fragmentBinding;
288*f585d8a3SJacky Wang 
TestViewWithFragmentBindings(Context context)289*f585d8a3SJacky Wang     TestViewWithFragmentBindings(Context context) {
290*f585d8a3SJacky Wang       super(context);
291*f585d8a3SJacky Wang     }
292*f585d8a3SJacky Wang   }
293*f585d8a3SJacky Wang 
294*f585d8a3SJacky Wang   @AndroidEntryPoint(Service.class)
295*f585d8a3SJacky Wang   public static final class TestService extends Hilt_InjectionTest_TestService {
296*f585d8a3SJacky Wang     @Inject @ApplicationLevel String appBinding;
297*f585d8a3SJacky Wang     @Inject @ServiceLevel String serviceBinding;
298*f585d8a3SJacky Wang 
299*f585d8a3SJacky Wang     @Override
onBind(Intent intent)300*f585d8a3SJacky Wang     public IBinder onBind(Intent intent) {
301*f585d8a3SJacky Wang       return null;
302*f585d8a3SJacky Wang     }
303*f585d8a3SJacky Wang   }
304*f585d8a3SJacky Wang 
305*f585d8a3SJacky Wang   @AndroidEntryPoint(IntentService.class)
306*f585d8a3SJacky Wang   public static final class TestIntentService extends Hilt_InjectionTest_TestIntentService {
307*f585d8a3SJacky Wang     private static final String NAME = "TestIntentServiceName";
308*f585d8a3SJacky Wang     @Inject @ApplicationLevel String appBinding;
309*f585d8a3SJacky Wang     @Inject @ServiceLevel String serviceBinding;
310*f585d8a3SJacky Wang 
TestIntentService()311*f585d8a3SJacky Wang     TestIntentService() {
312*f585d8a3SJacky Wang       super(NAME);
313*f585d8a3SJacky Wang     }
314*f585d8a3SJacky Wang 
315*f585d8a3SJacky Wang     @Override
onHandleIntent(Intent intent)316*f585d8a3SJacky Wang     public void onHandleIntent(Intent intent) {}
317*f585d8a3SJacky Wang   }
318*f585d8a3SJacky Wang 
319*f585d8a3SJacky Wang   @AndroidEntryPoint(BroadcastReceiver.class)
320*f585d8a3SJacky Wang   public static final class TestBroadcastReceiver extends Hilt_InjectionTest_TestBroadcastReceiver {
321*f585d8a3SJacky Wang     @Inject @ApplicationLevel String appBinding;
322*f585d8a3SJacky Wang     Intent lastIntent = null;
323*f585d8a3SJacky Wang 
324*f585d8a3SJacky Wang     @Override
onReceive(Context context, Intent intent)325*f585d8a3SJacky Wang     public void onReceive(Context context, Intent intent) {
326*f585d8a3SJacky Wang       super.onReceive(context, intent);
327*f585d8a3SJacky Wang       lastIntent = intent;
328*f585d8a3SJacky Wang     }
329*f585d8a3SJacky Wang   }
330*f585d8a3SJacky Wang 
331*f585d8a3SJacky Wang   @AndroidEntryPoint(BaseBroadcastReceiver.class)
332*f585d8a3SJacky Wang   public static final class TestBroadcastReceiverWithBaseImplementingOnReceive
333*f585d8a3SJacky Wang       extends Hilt_InjectionTest_TestBroadcastReceiverWithBaseImplementingOnReceive {
334*f585d8a3SJacky Wang     @Inject @ApplicationLevel String appBinding;
335*f585d8a3SJacky Wang     Intent baseLastIntent = null;
336*f585d8a3SJacky Wang 
337*f585d8a3SJacky Wang     @Override
onReceive(Context context, Intent intent)338*f585d8a3SJacky Wang     public void onReceive(Context context, Intent intent) {
339*f585d8a3SJacky Wang       super.onReceive(context, intent);
340*f585d8a3SJacky Wang       baseLastIntent = intent;
341*f585d8a3SJacky Wang     }
342*f585d8a3SJacky Wang   }
343*f585d8a3SJacky Wang 
344*f585d8a3SJacky Wang   abstract static class BaseBroadcastReceiver extends BroadcastReceiver {
345*f585d8a3SJacky Wang     Intent lastIntent = null;
346*f585d8a3SJacky Wang 
347*f585d8a3SJacky Wang     @Override
onReceive(Context context, Intent intent)348*f585d8a3SJacky Wang     public void onReceive(Context context, Intent intent) {
349*f585d8a3SJacky Wang       lastIntent = intent;
350*f585d8a3SJacky Wang     }
351*f585d8a3SJacky Wang   }
352*f585d8a3SJacky Wang 
353*f585d8a3SJacky Wang   @Rule public final HiltAndroidRule rule = new HiltAndroidRule(this);
354*f585d8a3SJacky Wang 
355*f585d8a3SJacky Wang   @Inject @ApplicationLevel String appBinding;
356*f585d8a3SJacky Wang 
357*f585d8a3SJacky Wang   @Before
setup()358*f585d8a3SJacky Wang   public void setup() {
359*f585d8a3SJacky Wang     rule.inject();
360*f585d8a3SJacky Wang   }
361*f585d8a3SJacky Wang 
362*f585d8a3SJacky Wang   @Test
testAppInjection()363*f585d8a3SJacky Wang   public void testAppInjection() throws Exception {
364*f585d8a3SJacky Wang     assertThat(appBinding).isEqualTo(APP_BINDING);
365*f585d8a3SJacky Wang   }
366*f585d8a3SJacky Wang 
367*f585d8a3SJacky Wang   @Test
testActivityInjection()368*f585d8a3SJacky Wang   public void testActivityInjection() throws Exception {
369*f585d8a3SJacky Wang     ActivityController<TestActivity> controller = Robolectric.buildActivity(TestActivity.class);
370*f585d8a3SJacky Wang 
371*f585d8a3SJacky Wang     assertThat(controller.get().onCreateCalled).isFalse();
372*f585d8a3SJacky Wang     controller.create();
373*f585d8a3SJacky Wang     assertThat(controller.get().onCreateCalled).isTrue();
374*f585d8a3SJacky Wang   }
375*f585d8a3SJacky Wang 
376*f585d8a3SJacky Wang   @Test
testFragmentInjection()377*f585d8a3SJacky Wang   public void testFragmentInjection() throws Exception {
378*f585d8a3SJacky Wang     TestFragment fragment = new TestFragment();
379*f585d8a3SJacky Wang     assertThat(fragment.onAttachContextCalled).isFalse();
380*f585d8a3SJacky Wang     assertThat(fragment.onAttachActivityCalled).isFalse();
381*f585d8a3SJacky Wang     setupFragment(TestActivity.class, fragment);
382*f585d8a3SJacky Wang     assertThat(fragment.onAttachContextCalled).isTrue();
383*f585d8a3SJacky Wang     assertThat(fragment.onAttachActivityCalled).isTrue();
384*f585d8a3SJacky Wang   }
385*f585d8a3SJacky Wang 
386*f585d8a3SJacky Wang   @Test
testParameterizedFragmentInjection()387*f585d8a3SJacky Wang   public void testParameterizedFragmentInjection() throws Exception {
388*f585d8a3SJacky Wang     TestParameterizedFragment fragment = new TestParameterizedFragment();
389*f585d8a3SJacky Wang     assertThat(fragment.onAttachContextCalled).isFalse();
390*f585d8a3SJacky Wang     assertThat(fragment.onAttachActivityCalled).isFalse();
391*f585d8a3SJacky Wang     setupFragment(TestActivity.class, fragment);
392*f585d8a3SJacky Wang     assertThat(fragment.onAttachContextCalled).isTrue();
393*f585d8a3SJacky Wang     assertThat(fragment.onAttachActivityCalled).isTrue();
394*f585d8a3SJacky Wang   }
395*f585d8a3SJacky Wang 
396*f585d8a3SJacky Wang   @Test
testViewNoFragmentBindingsWithActivity()397*f585d8a3SJacky Wang   public void testViewNoFragmentBindingsWithActivity() throws Exception {
398*f585d8a3SJacky Wang     TestActivity activity = Robolectric.setupActivity(TestActivity.class);
399*f585d8a3SJacky Wang     TestView view = new TestView(activity);
400*f585d8a3SJacky Wang     assertThat(view.appBinding).isEqualTo(APP_BINDING);
401*f585d8a3SJacky Wang     assertThat(view.activityBinding).isEqualTo(ACTIVITY_BINDING);
402*f585d8a3SJacky Wang   }
403*f585d8a3SJacky Wang 
404*f585d8a3SJacky Wang   @Test
testViewNoFragmentBindingsWithFragment()405*f585d8a3SJacky Wang   public void testViewNoFragmentBindingsWithFragment() throws Exception {
406*f585d8a3SJacky Wang     TestFragment fragment = setupFragment(TestActivity.class, new TestFragment());
407*f585d8a3SJacky Wang     TestView view = new TestView(fragment.getContext());
408*f585d8a3SJacky Wang     assertThat(view.appBinding).isEqualTo(APP_BINDING);
409*f585d8a3SJacky Wang     assertThat(view.activityBinding).isEqualTo(ACTIVITY_BINDING);
410*f585d8a3SJacky Wang   }
411*f585d8a3SJacky Wang 
412*f585d8a3SJacky Wang   @Test
testViewNoFragmentBindingsWithFragment_secondConstructor()413*f585d8a3SJacky Wang   public void testViewNoFragmentBindingsWithFragment_secondConstructor() throws Exception {
414*f585d8a3SJacky Wang     TestFragment fragment = setupFragment(TestActivity.class, new TestFragment());
415*f585d8a3SJacky Wang     TestView view = new TestView(fragment.getContext(), /* attrs= */ null);
416*f585d8a3SJacky Wang     assertThat(view.appBinding).isEqualTo(APP_BINDING);
417*f585d8a3SJacky Wang     assertThat(view.activityBinding).isEqualTo(ACTIVITY_BINDING);
418*f585d8a3SJacky Wang   }
419*f585d8a3SJacky Wang 
420*f585d8a3SJacky Wang   @Test
testViewNoFragmentBindingsWithFragment_thirdConstructor()421*f585d8a3SJacky Wang   public void testViewNoFragmentBindingsWithFragment_thirdConstructor() throws Exception {
422*f585d8a3SJacky Wang     TestFragment fragment = setupFragment(TestActivity.class, new TestFragment());
423*f585d8a3SJacky Wang     TestView view = new TestView(fragment.getContext(), /* attrs= */ null, /* defStyleAttr= */ 0);
424*f585d8a3SJacky Wang     assertThat(view.appBinding).isEqualTo(APP_BINDING);
425*f585d8a3SJacky Wang     assertThat(view.activityBinding).isEqualTo(ACTIVITY_BINDING);
426*f585d8a3SJacky Wang   }
427*f585d8a3SJacky Wang 
428*f585d8a3SJacky Wang   @Test
429*f585d8a3SJacky Wang   @Config(sdk = 21)
testViewNoFragmentBindingsWithFragment_fourthConstructor_presentOnTwentyOne()430*f585d8a3SJacky Wang   public void testViewNoFragmentBindingsWithFragment_fourthConstructor_presentOnTwentyOne()
431*f585d8a3SJacky Wang       throws Exception {
432*f585d8a3SJacky Wang     TestFragment fragment = setupFragment(TestActivity.class, new TestFragment());
433*f585d8a3SJacky Wang     TestView view =
434*f585d8a3SJacky Wang         new TestView(
435*f585d8a3SJacky Wang             fragment.getContext(), /* attrs= */ null, /* defStyleAttr= */ 0, /* defStyleRes= */ 0);
436*f585d8a3SJacky Wang     assertThat(view.appBinding).isEqualTo(APP_BINDING);
437*f585d8a3SJacky Wang     assertThat(view.activityBinding).isEqualTo(ACTIVITY_BINDING);
438*f585d8a3SJacky Wang   }
439*f585d8a3SJacky Wang 
440*f585d8a3SJacky Wang   @Test
testServiceInjection()441*f585d8a3SJacky Wang   public void testServiceInjection() throws Exception {
442*f585d8a3SJacky Wang     TestService testService = Robolectric.setupService(TestService.class);
443*f585d8a3SJacky Wang     assertThat(testService.appBinding).isEqualTo(APP_BINDING);
444*f585d8a3SJacky Wang     assertThat(testService.serviceBinding).isEqualTo(SERVICE_BINDING);
445*f585d8a3SJacky Wang   }
446*f585d8a3SJacky Wang 
447*f585d8a3SJacky Wang   @Test
testIntentServiceInjection()448*f585d8a3SJacky Wang   public void testIntentServiceInjection() throws Exception {
449*f585d8a3SJacky Wang     TestIntentService testIntentService = Robolectric.setupService(TestIntentService.class);
450*f585d8a3SJacky Wang     assertThat(testIntentService.appBinding).isEqualTo(APP_BINDING);
451*f585d8a3SJacky Wang     assertThat(testIntentService.serviceBinding).isEqualTo(SERVICE_BINDING);
452*f585d8a3SJacky Wang   }
453*f585d8a3SJacky Wang 
454*f585d8a3SJacky Wang   @Test
testBroadcastReceiverInjection()455*f585d8a3SJacky Wang   public void testBroadcastReceiverInjection() throws Exception {
456*f585d8a3SJacky Wang     TestBroadcastReceiver testBroadcastReceiver = new TestBroadcastReceiver();
457*f585d8a3SJacky Wang     Intent intent = new Intent();
458*f585d8a3SJacky Wang     testBroadcastReceiver.onReceive(getApplicationContext(), intent);
459*f585d8a3SJacky Wang     assertThat(testBroadcastReceiver.appBinding).isEqualTo(APP_BINDING);
460*f585d8a3SJacky Wang     assertThat(testBroadcastReceiver.lastIntent).isSameInstanceAs(intent);
461*f585d8a3SJacky Wang   }
462*f585d8a3SJacky Wang 
463*f585d8a3SJacky Wang   @Test
testBroadcastReceiverWithBaseImplementingOnReceiveInjection()464*f585d8a3SJacky Wang   public void testBroadcastReceiverWithBaseImplementingOnReceiveInjection() throws Exception {
465*f585d8a3SJacky Wang     TestBroadcastReceiverWithBaseImplementingOnReceive testBroadcastReceiver =
466*f585d8a3SJacky Wang         new TestBroadcastReceiverWithBaseImplementingOnReceive();
467*f585d8a3SJacky Wang     Intent intent = new Intent();
468*f585d8a3SJacky Wang     testBroadcastReceiver.onReceive(getApplicationContext(), intent);
469*f585d8a3SJacky Wang     assertThat(testBroadcastReceiver.appBinding).isEqualTo(APP_BINDING);
470*f585d8a3SJacky Wang     assertThat(testBroadcastReceiver.lastIntent).isSameInstanceAs(intent);
471*f585d8a3SJacky Wang     assertThat(testBroadcastReceiver.baseLastIntent).isSameInstanceAs(intent);
472*f585d8a3SJacky Wang   }
473*f585d8a3SJacky Wang 
474*f585d8a3SJacky Wang   @Test
testViewWithFragmentBindingsWithFragment()475*f585d8a3SJacky Wang   public void testViewWithFragmentBindingsWithFragment() throws Exception {
476*f585d8a3SJacky Wang     TestFragment fragment = setupFragment(TestActivity.class, new TestFragment());
477*f585d8a3SJacky Wang 
478*f585d8a3SJacky Wang     Context fragmentContext = fragment.getContext();
479*f585d8a3SJacky Wang     TestViewWithFragmentBindings view = new TestViewWithFragmentBindings(fragmentContext);
480*f585d8a3SJacky Wang     assertThat(view.appBinding).isEqualTo(APP_BINDING);
481*f585d8a3SJacky Wang     assertThat(view.activityBinding).isEqualTo(ACTIVITY_BINDING);
482*f585d8a3SJacky Wang     assertThat(view.fragmentBinding).isEqualTo(FRAGMENT_BINDING);
483*f585d8a3SJacky Wang   }
484*f585d8a3SJacky Wang 
485*f585d8a3SJacky Wang   @Test
testViewWithFragmentBindingsFailsWithActivity()486*f585d8a3SJacky Wang   public void testViewWithFragmentBindingsFailsWithActivity() throws Exception {
487*f585d8a3SJacky Wang     TestActivity activity = Robolectric.setupActivity(TestActivity.class);
488*f585d8a3SJacky Wang     try {
489*f585d8a3SJacky Wang       new TestViewWithFragmentBindings(activity);
490*f585d8a3SJacky Wang       fail("Expected test to fail but it passes!");
491*f585d8a3SJacky Wang     } catch (IllegalStateException e) {
492*f585d8a3SJacky Wang       assertThat(e)
493*f585d8a3SJacky Wang           .hasMessageThat()
494*f585d8a3SJacky Wang           .contains(
495*f585d8a3SJacky Wang               "@WithFragmentBindings Hilt view must be attached to an @AndroidEntryPoint Fragment");
496*f585d8a3SJacky Wang     }
497*f585d8a3SJacky Wang   }
498*f585d8a3SJacky Wang 
499*f585d8a3SJacky Wang   @Test
testFragmentAttachedToNonHiltActivityFails()500*f585d8a3SJacky Wang   public void testFragmentAttachedToNonHiltActivityFails() throws Exception {
501*f585d8a3SJacky Wang     NonHiltActivity activity = Robolectric.setupActivity(NonHiltActivity.class);
502*f585d8a3SJacky Wang     try {
503*f585d8a3SJacky Wang       activity
504*f585d8a3SJacky Wang           .getSupportFragmentManager()
505*f585d8a3SJacky Wang           .beginTransaction()
506*f585d8a3SJacky Wang           .add(new TestFragment(), null)
507*f585d8a3SJacky Wang           .commitNow();
508*f585d8a3SJacky Wang       fail("Expected test to fail but it passes!");
509*f585d8a3SJacky Wang     } catch (IllegalStateException e) {
510*f585d8a3SJacky Wang       assertThat(e)
511*f585d8a3SJacky Wang           .hasMessageThat()
512*f585d8a3SJacky Wang           .contains("Hilt Fragments must be attached to an @AndroidEntryPoint Activity");
513*f585d8a3SJacky Wang     }
514*f585d8a3SJacky Wang   }
515*f585d8a3SJacky Wang 
516*f585d8a3SJacky Wang   @Test
testViewAttachedToNonHiltActivityFails()517*f585d8a3SJacky Wang   public void testViewAttachedToNonHiltActivityFails() throws Exception {
518*f585d8a3SJacky Wang     NonHiltActivity activity = Robolectric.setupActivity(NonHiltActivity.class);
519*f585d8a3SJacky Wang     try {
520*f585d8a3SJacky Wang       new TestView(activity);
521*f585d8a3SJacky Wang       fail("Expected test to fail but it passes!");
522*f585d8a3SJacky Wang     } catch (IllegalStateException e) {
523*f585d8a3SJacky Wang       assertThat(e)
524*f585d8a3SJacky Wang           .hasMessageThat()
525*f585d8a3SJacky Wang           .contains("Hilt view must be attached to an @AndroidEntryPoint Fragment or Activity");
526*f585d8a3SJacky Wang     }
527*f585d8a3SJacky Wang   }
528*f585d8a3SJacky Wang 
529*f585d8a3SJacky Wang   @Test
testViewAttachedToNonHiltFragmentFails()530*f585d8a3SJacky Wang   public void testViewAttachedToNonHiltFragmentFails() throws Exception {
531*f585d8a3SJacky Wang     NonHiltActivity activity = Robolectric.setupActivity(NonHiltActivity.class);
532*f585d8a3SJacky Wang     NonHiltFragment fragment = new NonHiltFragment();
533*f585d8a3SJacky Wang     activity.getSupportFragmentManager().beginTransaction().add(fragment, null).commitNow();
534*f585d8a3SJacky Wang     Context nonHiltContext = fragment.getContext();
535*f585d8a3SJacky Wang     try {
536*f585d8a3SJacky Wang       new TestView(nonHiltContext);
537*f585d8a3SJacky Wang       fail("Expected test to fail but it passes!");
538*f585d8a3SJacky Wang     } catch (IllegalStateException e) {
539*f585d8a3SJacky Wang       assertThat(e)
540*f585d8a3SJacky Wang           .hasMessageThat()
541*f585d8a3SJacky Wang           .contains("Hilt view must be attached to an @AndroidEntryPoint Fragment or Activity");
542*f585d8a3SJacky Wang     }
543*f585d8a3SJacky Wang   }
544*f585d8a3SJacky Wang 
545*f585d8a3SJacky Wang   @Test
testViewAttachedToApplicationContextFails()546*f585d8a3SJacky Wang   public void testViewAttachedToApplicationContextFails() throws Exception {
547*f585d8a3SJacky Wang     try {
548*f585d8a3SJacky Wang       new TestView(getApplicationContext());
549*f585d8a3SJacky Wang       fail("Expected test to fail but it passes!");
550*f585d8a3SJacky Wang     } catch (IllegalStateException e) {
551*f585d8a3SJacky Wang       assertThat(e)
552*f585d8a3SJacky Wang           .hasMessageThat()
553*f585d8a3SJacky Wang           .contains(
554*f585d8a3SJacky Wang               "Hilt view cannot be created using the application context. "
555*f585d8a3SJacky Wang                   + "Use a Hilt Fragment or Activity context");
556*f585d8a3SJacky Wang     }
557*f585d8a3SJacky Wang   }
558*f585d8a3SJacky Wang 
559*f585d8a3SJacky Wang   /** Hilt Activity that manually calls inject(). */
560*f585d8a3SJacky Wang   @AndroidEntryPoint(FragmentActivity.class)
561*f585d8a3SJacky Wang   public static final class DoubleInjectActivity extends Hilt_InjectionTest_DoubleInjectActivity {
562*f585d8a3SJacky Wang     @Inject Long counter;
563*f585d8a3SJacky Wang 
564*f585d8a3SJacky Wang     @Override
onCreate(Bundle onSavedInstanceState)565*f585d8a3SJacky Wang     public void onCreate(Bundle onSavedInstanceState) {
566*f585d8a3SJacky Wang       inject();
567*f585d8a3SJacky Wang       super.onCreate(onSavedInstanceState);
568*f585d8a3SJacky Wang     }
569*f585d8a3SJacky Wang   }
570*f585d8a3SJacky Wang 
571*f585d8a3SJacky Wang   @Test
testActivityDoesNotInjectTwice()572*f585d8a3SJacky Wang   public void testActivityDoesNotInjectTwice() throws Exception {
573*f585d8a3SJacky Wang     ActivityController<DoubleInjectActivity> controller =
574*f585d8a3SJacky Wang         Robolectric.buildActivity(DoubleInjectActivity.class);
575*f585d8a3SJacky Wang     controller.create();
576*f585d8a3SJacky Wang     assertThat(controller.get().counter).isEqualTo(1L);
577*f585d8a3SJacky Wang   }
578*f585d8a3SJacky Wang 
579*f585d8a3SJacky Wang   /** Hilt Fragment that manually calls inject(). */
580*f585d8a3SJacky Wang   @AndroidEntryPoint(Fragment.class)
581*f585d8a3SJacky Wang   public static final class DoubleInjectFragment extends Hilt_InjectionTest_DoubleInjectFragment {
582*f585d8a3SJacky Wang     @Inject Long counter;
583*f585d8a3SJacky Wang 
584*f585d8a3SJacky Wang     @Override
onAttach(Context context)585*f585d8a3SJacky Wang     public void onAttach(Context context) {
586*f585d8a3SJacky Wang       inject();
587*f585d8a3SJacky Wang       super.onAttach(context);
588*f585d8a3SJacky Wang     }
589*f585d8a3SJacky Wang 
590*f585d8a3SJacky Wang     @Override
onAttach(Activity activity)591*f585d8a3SJacky Wang     public void onAttach(Activity activity) {
592*f585d8a3SJacky Wang       inject();
593*f585d8a3SJacky Wang       super.onAttach(activity);
594*f585d8a3SJacky Wang     }
595*f585d8a3SJacky Wang   }
596*f585d8a3SJacky Wang 
597*f585d8a3SJacky Wang   @Test
testFragmentDoesNotInjectTwice()598*f585d8a3SJacky Wang   public void testFragmentDoesNotInjectTwice() throws Exception {
599*f585d8a3SJacky Wang     DoubleInjectFragment fragment = setupFragment(TestActivity.class, new DoubleInjectFragment());
600*f585d8a3SJacky Wang     assertThat(fragment.counter).isEqualTo(1L);
601*f585d8a3SJacky Wang   }
602*f585d8a3SJacky Wang 
603*f585d8a3SJacky Wang   /** Hilt View that manually calls inject(). */
604*f585d8a3SJacky Wang   @AndroidEntryPoint(LinearLayout.class)
605*f585d8a3SJacky Wang   public static final class DoubleInjectView extends Hilt_InjectionTest_DoubleInjectView {
606*f585d8a3SJacky Wang     @Inject Long counter;
607*f585d8a3SJacky Wang 
DoubleInjectView(Context context)608*f585d8a3SJacky Wang     DoubleInjectView(Context context) {
609*f585d8a3SJacky Wang       super(context);
610*f585d8a3SJacky Wang       inject();
611*f585d8a3SJacky Wang     }
612*f585d8a3SJacky Wang 
DoubleInjectView(Context context, AttributeSet attrs)613*f585d8a3SJacky Wang     DoubleInjectView(Context context, AttributeSet attrs) {
614*f585d8a3SJacky Wang       super(context, attrs);
615*f585d8a3SJacky Wang       inject();
616*f585d8a3SJacky Wang     }
617*f585d8a3SJacky Wang 
DoubleInjectView(Context context, AttributeSet attrs, int defStyleAttr)618*f585d8a3SJacky Wang     DoubleInjectView(Context context, AttributeSet attrs, int defStyleAttr) {
619*f585d8a3SJacky Wang       super(context, attrs, defStyleAttr);
620*f585d8a3SJacky Wang       inject();
621*f585d8a3SJacky Wang     }
622*f585d8a3SJacky Wang 
623*f585d8a3SJacky Wang     @TargetApi(21)
DoubleInjectView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes)624*f585d8a3SJacky Wang     DoubleInjectView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
625*f585d8a3SJacky Wang       super(context, attrs, defStyleAttr, defStyleRes);
626*f585d8a3SJacky Wang       inject();
627*f585d8a3SJacky Wang     }
628*f585d8a3SJacky Wang   }
629*f585d8a3SJacky Wang 
630*f585d8a3SJacky Wang   @Test
testViewDoesNotInjectTwice()631*f585d8a3SJacky Wang   public void testViewDoesNotInjectTwice() throws Exception {
632*f585d8a3SJacky Wang     TestActivity activity = Robolectric.setupActivity(TestActivity.class);
633*f585d8a3SJacky Wang     DoubleInjectView view = new DoubleInjectView(activity);
634*f585d8a3SJacky Wang     assertThat(view.counter).isEqualTo(1L);
635*f585d8a3SJacky Wang   }
636*f585d8a3SJacky Wang 
637*f585d8a3SJacky Wang   /** Hilt Service that manually calls inject(). */
638*f585d8a3SJacky Wang   @AndroidEntryPoint(Service.class)
639*f585d8a3SJacky Wang   public static final class DoubleInjectService extends Hilt_InjectionTest_DoubleInjectService {
640*f585d8a3SJacky Wang     @Inject Long counter;
641*f585d8a3SJacky Wang 
onCreate()642*f585d8a3SJacky Wang     @Override public void onCreate() {
643*f585d8a3SJacky Wang       inject();
644*f585d8a3SJacky Wang       super.onCreate();
645*f585d8a3SJacky Wang     }
646*f585d8a3SJacky Wang 
647*f585d8a3SJacky Wang     @Override
onBind(Intent intent)648*f585d8a3SJacky Wang     public IBinder onBind(Intent intent) {
649*f585d8a3SJacky Wang       return null;
650*f585d8a3SJacky Wang     }
651*f585d8a3SJacky Wang   }
652*f585d8a3SJacky Wang 
653*f585d8a3SJacky Wang   @Test
testServiceDoesNotInjectTwice()654*f585d8a3SJacky Wang   public void testServiceDoesNotInjectTwice() throws Exception {
655*f585d8a3SJacky Wang     DoubleInjectService testService = Robolectric.setupService(DoubleInjectService.class);
656*f585d8a3SJacky Wang     assertThat(testService.counter).isEqualTo(1L);
657*f585d8a3SJacky Wang   }
658*f585d8a3SJacky Wang 
659*f585d8a3SJacky Wang   /** Hilt BroadcastReceiver that manually calls inject(). */
660*f585d8a3SJacky Wang   @AndroidEntryPoint(BroadcastReceiver.class)
661*f585d8a3SJacky Wang   public static final class DoubleInjectBroadcastReceiver
662*f585d8a3SJacky Wang       extends Hilt_InjectionTest_DoubleInjectBroadcastReceiver {
663*f585d8a3SJacky Wang     @Inject Long counter;
664*f585d8a3SJacky Wang 
665*f585d8a3SJacky Wang     @Override
onReceive(Context context, Intent intent)666*f585d8a3SJacky Wang     public void onReceive(Context context, Intent intent) {
667*f585d8a3SJacky Wang       inject(context);
668*f585d8a3SJacky Wang       super.onReceive(context, intent);
669*f585d8a3SJacky Wang     }
670*f585d8a3SJacky Wang   }
671*f585d8a3SJacky Wang 
672*f585d8a3SJacky Wang   @Test
testBroadcastReceiverDoesNotInjectTwice()673*f585d8a3SJacky Wang   public void testBroadcastReceiverDoesNotInjectTwice() throws Exception {
674*f585d8a3SJacky Wang     DoubleInjectBroadcastReceiver testBroadcastReceiver = new DoubleInjectBroadcastReceiver();
675*f585d8a3SJacky Wang     Intent intent = new Intent();
676*f585d8a3SJacky Wang     testBroadcastReceiver.onReceive(getApplicationContext(), intent);
677*f585d8a3SJacky Wang     assertThat(testBroadcastReceiver.counter).isEqualTo(1L);
678*f585d8a3SJacky Wang   }
679*f585d8a3SJacky Wang 
setupFragment( Class<? extends FragmentActivity> activityClass, T fragment)680*f585d8a3SJacky Wang   private static <T extends Fragment> T setupFragment(
681*f585d8a3SJacky Wang       Class<? extends FragmentActivity> activityClass, T fragment) {
682*f585d8a3SJacky Wang     FragmentActivity activity = Robolectric.setupActivity(activityClass);
683*f585d8a3SJacky Wang     attachFragment(activity, fragment);
684*f585d8a3SJacky Wang     return fragment;
685*f585d8a3SJacky Wang   }
686*f585d8a3SJacky Wang 
attachFragment(FragmentActivity activity, Fragment fragment)687*f585d8a3SJacky Wang   private static void attachFragment(FragmentActivity activity, Fragment fragment) {
688*f585d8a3SJacky Wang     activity.getSupportFragmentManager().beginTransaction().add(fragment, "").commitNow();
689*f585d8a3SJacky Wang   }
690*f585d8a3SJacky Wang }
691