1 /* 2 * Copyright (C) 2021 The Dagger Authors. 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package dagger.hilt.android; 18 19 import static com.google.common.truth.Truth.assertThat; 20 import static dagger.hilt.android.OptionalInjectTestClasses.ACTIVITY_BINDING; 21 import static dagger.hilt.android.OptionalInjectTestClasses.APP_BINDING; 22 import static dagger.hilt.android.OptionalInjectTestClasses.FRAGMENT_BINDING; 23 import static dagger.hilt.android.OptionalInjectTestClasses.VIEW_BINDING; 24 import static dagger.hilt.android.migration.OptionalInjectCheck.wasInjectedByHilt; 25 import static org.junit.Assert.assertThrows; 26 27 import android.content.Intent; 28 import android.os.Build; 29 import androidx.fragment.app.Fragment; 30 import androidx.fragment.app.FragmentActivity; 31 import androidx.lifecycle.ViewModelProvider; 32 import androidx.test.core.app.ApplicationProvider; 33 import androidx.test.ext.junit.runners.AndroidJUnit4; 34 import dagger.hilt.android.OptionalInjectTestClasses.NonHiltViewModel; 35 import dagger.hilt.android.OptionalInjectTestClasses.NonOptionalSubclassActivity; 36 import dagger.hilt.android.OptionalInjectTestClasses.OptionalSubclassActivity; 37 import dagger.hilt.android.OptionalInjectTestClasses.TestActivity; 38 import dagger.hilt.android.OptionalInjectTestClasses.TestBroadcastReceiver; 39 import dagger.hilt.android.OptionalInjectTestClasses.TestFragment; 40 import dagger.hilt.android.OptionalInjectTestClasses.TestIntentService; 41 import dagger.hilt.android.OptionalInjectTestClasses.TestService; 42 import dagger.hilt.android.OptionalInjectTestClasses.TestView; 43 import dagger.hilt.android.OptionalInjectTestClasses.TestViewModel; 44 import dagger.hilt.android.OptionalInjectTestClasses.TestWithFragmentBindingsView; 45 import dagger.hilt.android.testing.HiltAndroidRule; 46 import dagger.hilt.android.testing.HiltAndroidTest; 47 import dagger.hilt.android.testing.HiltTestApplication; 48 import org.junit.Rule; 49 import org.junit.Test; 50 import org.junit.runner.RunWith; 51 import org.robolectric.Robolectric; 52 import org.robolectric.annotation.Config; 53 54 /** Tests that optional inject works with a Hilt root. */ 55 @HiltAndroidTest 56 @RunWith(AndroidJUnit4.class) 57 // Robolectric requires Java9 to run API 29 and above, so use API 28 instead 58 @Config(sdk = Build.VERSION_CODES.P, application = HiltTestApplication.class) 59 public final class OptionalInjectWithHiltTest { 60 @Rule public final HiltAndroidRule rules = new HiltAndroidRule(this); 61 62 @Test testActivityInjection()63 public void testActivityInjection() throws Exception { 64 TestActivity testActivity = Robolectric.setupActivity(TestActivity.class); 65 assertThat(testActivity.testActivityBinding).isEqualTo(ACTIVITY_BINDING); 66 assertThat(testActivity.wasInjectedByHilt()).isTrue(); 67 assertThat(wasInjectedByHilt(testActivity)).isTrue(); 68 } 69 70 @Test testNonOptionalSubclassActivityInjection()71 public void testNonOptionalSubclassActivityInjection() throws Exception { 72 NonOptionalSubclassActivity testActivity = Robolectric.setupActivity( 73 NonOptionalSubclassActivity.class); 74 assertThat(testActivity.testActivityBinding).isEqualTo(ACTIVITY_BINDING); 75 assertThat(testActivity.testActivitySubclassBinding).isEqualTo(ACTIVITY_BINDING); 76 assertThat(testActivity.wasInjectedByHilt()).isTrue(); 77 assertThat(wasInjectedByHilt(testActivity)).isTrue(); 78 } 79 80 @Test testOptionalSubclassActivityInjection()81 public void testOptionalSubclassActivityInjection() throws Exception { 82 OptionalSubclassActivity testActivity = Robolectric.setupActivity( 83 OptionalSubclassActivity.class); 84 assertThat(testActivity.testActivityBinding).isEqualTo(ACTIVITY_BINDING); 85 assertThat(testActivity.testActivitySubclassBinding).isEqualTo(ACTIVITY_BINDING); 86 assertThat(testActivity.wasInjectedByHilt()).isTrue(); 87 assertThat(wasInjectedByHilt(testActivity)).isTrue(); 88 } 89 90 @Test testFragmentInjection()91 public void testFragmentInjection() throws Exception { 92 TestActivity testActivity = Robolectric.setupActivity(TestActivity.class); 93 TestFragment testFragment = new TestFragment(); 94 testActivity.getSupportFragmentManager() 95 .beginTransaction() 96 .add(testFragment, null) 97 .commitNow(); 98 assertThat(testFragment.testFragmentBinding).isEqualTo(FRAGMENT_BINDING); 99 assertThat(testFragment.wasInjectedByHilt()).isTrue(); 100 assertThat(wasInjectedByHilt(testFragment)).isTrue(); 101 } 102 103 @Test testFragmentInjectionWithNonHiltActivityWithHiltRoot()104 public void testFragmentInjectionWithNonHiltActivityWithHiltRoot() throws Exception { 105 FragmentActivity testActivity = Robolectric.setupActivity(FragmentActivity.class); 106 TestFragment testFragment = new TestFragment(); 107 testActivity.getSupportFragmentManager() 108 .beginTransaction() 109 .add(testFragment, null) 110 .commitNow(); 111 assertThat(testFragment.testFragmentBinding).isNull(); 112 assertThat(testFragment.wasInjectedByHilt()).isFalse(); 113 assertThat(wasInjectedByHilt(testFragment)).isFalse(); 114 } 115 116 @Test testViewInjection()117 public void testViewInjection() throws Exception { 118 TestActivity testActivity = Robolectric.setupActivity(TestActivity.class); 119 TestView testView = new TestView(testActivity); 120 assertThat(testView.testViewBinding).isEqualTo(VIEW_BINDING); 121 assertThat(testView.wasInjectedByHilt()).isTrue(); 122 assertThat(wasInjectedByHilt(testView)).isTrue(); 123 } 124 125 @Test testViewInjectionWithNonHiltActivityWithHiltRoot()126 public void testViewInjectionWithNonHiltActivityWithHiltRoot() throws Exception { 127 FragmentActivity testActivity = Robolectric.setupActivity(FragmentActivity.class); 128 TestView testView = new TestView(testActivity); 129 assertThat(testView.testViewBinding).isNull(); 130 assertThat(testView.wasInjectedByHilt()).isFalse(); 131 assertThat(wasInjectedByHilt(testView)).isFalse(); 132 } 133 134 @Test testViewWithFragmentBindingsInjection()135 public void testViewWithFragmentBindingsInjection() throws Exception { 136 TestActivity testActivity = Robolectric.setupActivity(TestActivity.class); 137 TestFragment testFragment = new TestFragment(); 138 testActivity.getSupportFragmentManager() 139 .beginTransaction() 140 .add(testFragment, null) 141 .commitNow(); 142 143 TestWithFragmentBindingsView testView = new TestWithFragmentBindingsView( 144 testFragment.getLayoutInflater().getContext()); 145 assertThat(testView.testViewBinding).isEqualTo(VIEW_BINDING); 146 assertThat(testView.wasInjectedByHilt()).isTrue(); 147 assertThat(wasInjectedByHilt(testView)).isTrue(); 148 } 149 150 @Test testViewWithFragmentBindingsInjectionWithNonHiltFragmentWithHiltRoot()151 public void testViewWithFragmentBindingsInjectionWithNonHiltFragmentWithHiltRoot() 152 throws Exception { 153 TestActivity testActivity = Robolectric.setupActivity(TestActivity.class); 154 Fragment testFragment = new Fragment(); 155 testActivity.getSupportFragmentManager() 156 .beginTransaction() 157 .add(testFragment, null) 158 .commitNow(); 159 160 TestWithFragmentBindingsView testView = new TestWithFragmentBindingsView( 161 testFragment.getLayoutInflater().getContext()); 162 assertThat(testView.testViewBinding).isNull(); 163 assertThat(testView.wasInjectedByHilt()).isFalse(); 164 assertThat(wasInjectedByHilt(testView)).isFalse(); 165 } 166 167 @Test testHiltViewModels()168 public void testHiltViewModels() { 169 TestActivity testActivity = Robolectric.setupActivity(TestActivity.class); 170 TestFragment testFragment = new TestFragment(); 171 testActivity.getSupportFragmentManager() 172 .beginTransaction() 173 .add(testFragment, null) 174 .commitNow(); 175 assertThat(new ViewModelProvider(testActivity).get(TestViewModel.class).appBinding) 176 .isEqualTo(APP_BINDING); 177 assertThat(new ViewModelProvider(testActivity).get(NonHiltViewModel.class)).isNotNull(); 178 assertThat(new ViewModelProvider(testFragment).get(TestViewModel.class).appBinding) 179 .isEqualTo(APP_BINDING); 180 assertThat(new ViewModelProvider(testFragment).get(NonHiltViewModel.class)).isNotNull(); 181 } 182 183 @Test testHiltViewModelsWithNonHiltActivityWithHiltRoot()184 public void testHiltViewModelsWithNonHiltActivityWithHiltRoot() throws Exception { 185 FragmentActivity testActivity = Robolectric.setupActivity(FragmentActivity.class); 186 TestFragment testFragment = new TestFragment(); 187 testActivity.getSupportFragmentManager() 188 .beginTransaction() 189 .add(testFragment, null) 190 .commitNow(); 191 assertThat(new ViewModelProvider(testActivity).get(NonHiltViewModel.class)).isNotNull(); 192 assertThat(new ViewModelProvider(testFragment).get(NonHiltViewModel.class)).isNotNull(); 193 194 // Hilt View Models aren't usable in this case, so check that it throws. We only test with the 195 // owner as the fragment since the activity is just a plain FragmentActivity. 196 RuntimeException exception = 197 assertThrows( 198 RuntimeException.class, 199 () -> new ViewModelProvider(testFragment).get(TestViewModel.class)); 200 assertThat(exception) 201 .hasMessageThat() 202 .contains("TestViewModel"); 203 } 204 205 @Test testServiceInjection()206 public void testServiceInjection() throws Exception { 207 TestService testService = Robolectric.setupService(TestService.class); 208 assertThat(testService.testAppBinding).isEqualTo(APP_BINDING); 209 assertThat(testService.wasInjectedByHilt()).isTrue(); 210 assertThat(wasInjectedByHilt(testService)).isTrue(); 211 } 212 213 @Test testIntentServiceInjection()214 public void testIntentServiceInjection() throws Exception { 215 TestIntentService testIntentService = Robolectric.setupService(TestIntentService.class); 216 assertThat(testIntentService.testAppBinding).isEqualTo(APP_BINDING); 217 assertThat(testIntentService.wasInjectedByHilt()).isTrue(); 218 assertThat(wasInjectedByHilt(testIntentService)).isTrue(); 219 } 220 221 @Test testBroadcastReceiverInjection()222 public void testBroadcastReceiverInjection() throws Exception { 223 TestBroadcastReceiver testBroadcastReceiver = new TestBroadcastReceiver(); 224 Intent intent = new Intent(); 225 testBroadcastReceiver.onReceive(ApplicationProvider.getApplicationContext(), intent); 226 assertThat(testBroadcastReceiver.testAppBinding).isEqualTo(APP_BINDING); 227 assertThat(testBroadcastReceiver.wasInjectedByHilt()).isTrue(); 228 assertThat(wasInjectedByHilt(testBroadcastReceiver)).isTrue(); 229 } 230 } 231