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 androidx.test.core.app.ApplicationProvider.getApplicationContext;
20 import static com.google.common.truth.Truth.assertThat;
21 import static org.junit.Assert.assertThrows;
22 
23 import android.os.Build;
24 import androidx.test.ext.junit.runners.AndroidJUnit4;
25 import dagger.hilt.EntryPoint;
26 import dagger.hilt.InstallIn;
27 import dagger.hilt.android.internal.testing.TestApplicationComponentManager;
28 import dagger.hilt.android.testing.HiltAndroidRule;
29 import dagger.hilt.android.testing.HiltAndroidTest;
30 import dagger.hilt.android.testing.HiltTestApplication;
31 import dagger.hilt.components.SingletonComponent;
32 import javax.inject.Inject;
33 import javax.inject.Singleton;
34 import org.junit.Rule;
35 import org.junit.Test;
36 import org.junit.runner.RunWith;
37 import org.robolectric.annotation.Config;
38 
39 // The main purpose of this test is to check the error messages if EarlyEntryPoints is called
40 // without the EarlyComponent being generated (i.e. if no @EarlyEntryPoints are defined).
41 @HiltAndroidTest
42 @RunWith(AndroidJUnit4.class)
43 // Robolectric requires Java9 to run API 29 and above, so use API 28 instead
44 @Config(sdk = Build.VERSION_CODES.P, application = HiltTestApplication.class)
45 public final class EarlyEntryPointNoEntryPointsDefinedTest {
46   @EntryPoint
47   @InstallIn(SingletonComponent.class)
48   interface FooEntryPoint {
foo()49     Foo foo();
50   }
51 
52   @Singleton
53   public static class Foo {
54     @Inject
Foo()55     Foo() {}
56   }
57 
58   @Rule public HiltAndroidRule rule = new HiltAndroidRule(this);
59 
60   @Test
testEarlyComponentDoesNotExist()61   public void testEarlyComponentDoesNotExist() throws Exception {
62     HiltTestApplication app = (HiltTestApplication) getApplicationContext();
63     TestApplicationComponentManager componentManager =
64         (TestApplicationComponentManager) app.componentManager();
65 
66     RuntimeException exception =
67         assertThrows(RuntimeException.class, () -> componentManager.earlySingletonComponent());
68 
69     assertThat(exception)
70         .hasMessageThat()
71         .contains(
72             "The EarlyComponent was requested but does not exist. Check that you have "
73                 + "annotated your test class with @HiltAndroidTest and that the processor is "
74                 + "running over your test");
75   }
76 
77   @Test
testEarlyEntryPointsWrongEntryPointFails()78   public void testEarlyEntryPointsWrongEntryPointFails() throws Exception {
79     IllegalStateException exception =
80         assertThrows(
81             IllegalStateException.class,
82             () -> EarlyEntryPoints.get(getApplicationContext(), FooEntryPoint.class));
83 
84     assertThat(exception)
85         .hasMessageThat()
86         .contains(
87             "FooEntryPoint should be called with EntryPoints.get() rather than "
88                 + "EarlyEntryPoints.get()");
89   }
90 }
91