xref: /aosp_15_r20/external/dagger2/javatests/dagger/android/AndroidInjectionTest.java (revision f585d8a307d0621d6060bd7e80091fdcbf94fe27)
1*f585d8a3SJacky Wang /*
2*f585d8a3SJacky Wang  * Copyright (C) 2016 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.android;
18*f585d8a3SJacky Wang 
19*f585d8a3SJacky Wang import static com.google.common.truth.Truth.assertThat;
20*f585d8a3SJacky Wang import static org.junit.Assert.fail;
21*f585d8a3SJacky Wang import static org.robolectric.annotation.LooperMode.Mode.LEGACY;
22*f585d8a3SJacky Wang 
23*f585d8a3SJacky Wang import android.app.Activity;
24*f585d8a3SJacky Wang import android.app.Application;
25*f585d8a3SJacky Wang import android.app.Fragment;
26*f585d8a3SJacky Wang import android.os.Build;
27*f585d8a3SJacky Wang import androidx.test.ext.junit.runners.AndroidJUnit4;
28*f585d8a3SJacky Wang import org.junit.Test;
29*f585d8a3SJacky Wang import org.junit.runner.RunWith;
30*f585d8a3SJacky Wang import org.robolectric.Robolectric;
31*f585d8a3SJacky Wang import org.robolectric.annotation.Config;
32*f585d8a3SJacky Wang import org.robolectric.annotation.LooperMode;
33*f585d8a3SJacky Wang import org.robolectric.util.FragmentTestUtil;
34*f585d8a3SJacky Wang 
35*f585d8a3SJacky Wang @LooperMode(LEGACY)
36*f585d8a3SJacky Wang @RunWith(AndroidJUnit4.class)
37*f585d8a3SJacky Wang // Robolectric requires Java9 to run API 29 and above, so use API 28 instead
38*f585d8a3SJacky Wang @Config(sdk = Build.VERSION_CODES.P)
39*f585d8a3SJacky Wang public final class AndroidInjectionTest {
40*f585d8a3SJacky Wang 
41*f585d8a3SJacky Wang   // Most positive tests are performed in javatests/dagger/android/support/functional, but
42*f585d8a3SJacky Wang   // Robolectric's support for framework fragments is lacking, so we supplement those tests here:
43*f585d8a3SJacky Wang   public static class InjectableFragment extends Fragment {
44*f585d8a3SJacky Wang     String tag;
45*f585d8a3SJacky Wang   }
46*f585d8a3SJacky Wang 
fakeFragmentInjector(String tag)47*f585d8a3SJacky Wang   private static AndroidInjector<Object> fakeFragmentInjector(String tag) {
48*f585d8a3SJacky Wang     return instance -> {
49*f585d8a3SJacky Wang       if (instance instanceof InjectableFragment) {
50*f585d8a3SJacky Wang         ((InjectableFragment) instance).tag = tag;
51*f585d8a3SJacky Wang       }
52*f585d8a3SJacky Wang     };
53*f585d8a3SJacky Wang   }
54*f585d8a3SJacky Wang 
55*f585d8a3SJacky Wang   public static class ApplicationInjectsFragment extends Application implements HasAndroidInjector {
56*f585d8a3SJacky Wang     @Override
57*f585d8a3SJacky Wang     public AndroidInjector<Object> androidInjector() {
58*f585d8a3SJacky Wang       return fakeFragmentInjector("injected by app");
59*f585d8a3SJacky Wang     }
60*f585d8a3SJacky Wang   }
61*f585d8a3SJacky Wang 
62*f585d8a3SJacky Wang   @Config(application = ApplicationInjectsFragment.class)
63*f585d8a3SJacky Wang   @Test
64*f585d8a3SJacky Wang   public void fragmentInjectedByApplication() {
65*f585d8a3SJacky Wang     Activity activity = Robolectric.setupActivity(Activity.class);
66*f585d8a3SJacky Wang     InjectableFragment fragment = new InjectableFragment();
67*f585d8a3SJacky Wang     activity.getFragmentManager().beginTransaction().add(fragment, "tag").commit();
68*f585d8a3SJacky Wang 
69*f585d8a3SJacky Wang     AndroidInjection.inject(fragment);
70*f585d8a3SJacky Wang 
71*f585d8a3SJacky Wang     assertThat(fragment.tag).isEqualTo("injected by app");
72*f585d8a3SJacky Wang   }
73*f585d8a3SJacky Wang 
74*f585d8a3SJacky Wang   public static class ActivityInjectsFragment extends Activity implements HasAndroidInjector {
75*f585d8a3SJacky Wang     @Override
76*f585d8a3SJacky Wang     public AndroidInjector<Object> androidInjector() {
77*f585d8a3SJacky Wang       return fakeFragmentInjector("injected by activity");
78*f585d8a3SJacky Wang     }
79*f585d8a3SJacky Wang   }
80*f585d8a3SJacky Wang 
81*f585d8a3SJacky Wang   @Config(application = ApplicationInjectsFragment.class)
82*f585d8a3SJacky Wang   @Test
83*f585d8a3SJacky Wang   public void fragmentInjectedByActivity() {
84*f585d8a3SJacky Wang     ActivityInjectsFragment activity = Robolectric.setupActivity(ActivityInjectsFragment.class);
85*f585d8a3SJacky Wang     InjectableFragment fragment = new InjectableFragment();
86*f585d8a3SJacky Wang     activity.getFragmentManager().beginTransaction().add(fragment, "tag").commit();
87*f585d8a3SJacky Wang 
88*f585d8a3SJacky Wang     AndroidInjection.inject(fragment);
89*f585d8a3SJacky Wang 
90*f585d8a3SJacky Wang     assertThat(fragment.tag).isEqualTo("injected by activity");
91*f585d8a3SJacky Wang   }
92*f585d8a3SJacky Wang 
93*f585d8a3SJacky Wang   public static class ParentFragmentInjectsChildFragment extends Fragment
94*f585d8a3SJacky Wang       implements HasAndroidInjector {
95*f585d8a3SJacky Wang     @Override
96*f585d8a3SJacky Wang     public AndroidInjector<Object> androidInjector() {
97*f585d8a3SJacky Wang       return fakeFragmentInjector("injected by parent fragment");
98*f585d8a3SJacky Wang     }
99*f585d8a3SJacky Wang   }
100*f585d8a3SJacky Wang 
101*f585d8a3SJacky Wang   @Config(application = ApplicationInjectsFragment.class)
102*f585d8a3SJacky Wang   @Test
103*f585d8a3SJacky Wang   public void fragmentInjectedByParentFragment() {
104*f585d8a3SJacky Wang     ActivityInjectsFragment activity = Robolectric.setupActivity(ActivityInjectsFragment.class);
105*f585d8a3SJacky Wang     ParentFragmentInjectsChildFragment parentFragment = new ParentFragmentInjectsChildFragment();
106*f585d8a3SJacky Wang     InjectableFragment childFragment = new InjectableFragment();
107*f585d8a3SJacky Wang 
108*f585d8a3SJacky Wang     activity.getFragmentManager().beginTransaction().add(parentFragment, "tag").commit();
109*f585d8a3SJacky Wang     parentFragment
110*f585d8a3SJacky Wang         .getChildFragmentManager()
111*f585d8a3SJacky Wang         .beginTransaction()
112*f585d8a3SJacky Wang         .add(childFragment, "child-tag")
113*f585d8a3SJacky Wang         .commit();
114*f585d8a3SJacky Wang     AndroidInjection.inject(childFragment);
115*f585d8a3SJacky Wang 
116*f585d8a3SJacky Wang     assertThat(childFragment.tag).isEqualTo("injected by parent fragment");
117*f585d8a3SJacky Wang   }
118*f585d8a3SJacky Wang 
119*f585d8a3SJacky Wang   @Test
120*f585d8a3SJacky Wang   public void injectActivity_applicationDoesntImplementHasAndroidInjector() {
121*f585d8a3SJacky Wang     Activity activity = Robolectric.setupActivity(Activity.class);
122*f585d8a3SJacky Wang 
123*f585d8a3SJacky Wang     try {
124*f585d8a3SJacky Wang       AndroidInjection.inject(activity);
125*f585d8a3SJacky Wang       fail();
126*f585d8a3SJacky Wang     } catch (Exception e) {
127*f585d8a3SJacky Wang       assertThat(e)
128*f585d8a3SJacky Wang           .hasMessageThat()
129*f585d8a3SJacky Wang           .contains("Application does not implement dagger.android.HasAndroidInjector");
130*f585d8a3SJacky Wang     }
131*f585d8a3SJacky Wang   }
132*f585d8a3SJacky Wang 
133*f585d8a3SJacky Wang   @Test
134*f585d8a3SJacky Wang   public void injectFragment_hasFragmentInjectorNotFound() {
135*f585d8a3SJacky Wang     Fragment fragment = new Fragment();
136*f585d8a3SJacky Wang     FragmentTestUtil.startFragment(fragment);
137*f585d8a3SJacky Wang 
138*f585d8a3SJacky Wang     try {
139*f585d8a3SJacky Wang       AndroidInjection.inject(fragment);
140*f585d8a3SJacky Wang       fail();
141*f585d8a3SJacky Wang     } catch (Exception e) {
142*f585d8a3SJacky Wang       assertThat(e).hasMessageThat().contains("No injector was found");
143*f585d8a3SJacky Wang     }
144*f585d8a3SJacky Wang   }
145*f585d8a3SJacky Wang 
146*f585d8a3SJacky Wang   private static class ApplicationReturnsNull extends Application implements HasAndroidInjector {
147*f585d8a3SJacky Wang     @Override
148*f585d8a3SJacky Wang     public AndroidInjector<Object> androidInjector() {
149*f585d8a3SJacky Wang       return null;
150*f585d8a3SJacky Wang     }
151*f585d8a3SJacky Wang   }
152*f585d8a3SJacky Wang 
153*f585d8a3SJacky Wang   @Test
154*f585d8a3SJacky Wang   @Config(application = ApplicationReturnsNull.class)
155*f585d8a3SJacky Wang   public void activityInjector_returnsNull() {
156*f585d8a3SJacky Wang     Activity activity = Robolectric.setupActivity(Activity.class);
157*f585d8a3SJacky Wang 
158*f585d8a3SJacky Wang     try {
159*f585d8a3SJacky Wang       AndroidInjection.inject(activity);
160*f585d8a3SJacky Wang       fail();
161*f585d8a3SJacky Wang     } catch (Exception e) {
162*f585d8a3SJacky Wang       assertThat(e).hasMessageThat().contains("androidInjector() returned null");
163*f585d8a3SJacky Wang     }
164*f585d8a3SJacky Wang   }
165*f585d8a3SJacky Wang 
166*f585d8a3SJacky Wang   @Test
167*f585d8a3SJacky Wang   @Config(application = ApplicationReturnsNull.class)
168*f585d8a3SJacky Wang   public void fragmentInjector_returnsNull() {
169*f585d8a3SJacky Wang     Fragment fragment = new Fragment();
170*f585d8a3SJacky Wang     FragmentTestUtil.startFragment(fragment);
171*f585d8a3SJacky Wang 
172*f585d8a3SJacky Wang     try {
173*f585d8a3SJacky Wang       AndroidInjection.inject(fragment);
174*f585d8a3SJacky Wang       fail();
175*f585d8a3SJacky Wang     } catch (Exception e) {
176*f585d8a3SJacky Wang       assertThat(e).hasMessageThat().contains("androidInjector() returned null");
177*f585d8a3SJacky Wang     }
178*f585d8a3SJacky Wang   }
179*f585d8a3SJacky Wang 
180*f585d8a3SJacky Wang   @Test
181*f585d8a3SJacky Wang   public void injectActivity_nullInput() {
182*f585d8a3SJacky Wang     try {
183*f585d8a3SJacky Wang       AndroidInjection.inject((Activity) null);
184*f585d8a3SJacky Wang       fail();
185*f585d8a3SJacky Wang     } catch (NullPointerException e) {
186*f585d8a3SJacky Wang       assertThat(e).hasMessageThat().contains("activity");
187*f585d8a3SJacky Wang     }
188*f585d8a3SJacky Wang   }
189*f585d8a3SJacky Wang 
190*f585d8a3SJacky Wang   @Test
191*f585d8a3SJacky Wang   public void injectFragment_nullInput() {
192*f585d8a3SJacky Wang     try {
193*f585d8a3SJacky Wang       AndroidInjection.inject((Fragment) null);
194*f585d8a3SJacky Wang       fail();
195*f585d8a3SJacky Wang     } catch (NullPointerException e) {
196*f585d8a3SJacky Wang       assertThat(e).hasMessageThat().contains("fragment");
197*f585d8a3SJacky Wang     }
198*f585d8a3SJacky Wang   }
199*f585d8a3SJacky Wang }
200