• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2020 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 
21 import androidx.lifecycle.ViewModel;
22 import androidx.lifecycle.ViewModelProvider;
23 import android.os.Build;
24 import android.os.Bundle;
25 import androidx.annotation.Nullable;
26 import androidx.fragment.app.Fragment;
27 import androidx.fragment.app.FragmentActivity;
28 import androidx.test.core.app.ActivityScenario;
29 import androidx.test.ext.junit.runners.AndroidJUnit4;
30 import dagger.hilt.android.lifecycle.HiltViewModel;
31 import dagger.hilt.android.scopes.ViewModelScoped;
32 import dagger.hilt.android.testing.HiltAndroidRule;
33 import dagger.hilt.android.testing.HiltAndroidTest;
34 import dagger.hilt.android.testing.HiltTestApplication;
35 import javax.inject.Inject;
36 import org.junit.Rule;
37 import org.junit.Test;
38 import org.junit.runner.RunWith;
39 import org.robolectric.annotation.Config;
40 
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 class ViewModelScopedTest {
46 
47   @Rule public final HiltAndroidRule rule = new HiltAndroidRule(this);
48 
49   @Test
testViewModelScopeInFragment()50   public void testViewModelScopeInFragment() {
51     try (ActivityScenario<TestActivity> scenario = ActivityScenario.launch(TestActivity.class)) {
52       scenario.onActivity(
53           activity -> {
54             TestFragment fragment =
55                 (TestFragment) activity.getSupportFragmentManager().findFragmentByTag("tag");
56             assertThat(fragment.vm.one.bar).isEqualTo(fragment.vm.two.bar);
57           });
58     }
59   }
60 
61   @AndroidEntryPoint(FragmentActivity.class)
62   public static class TestActivity extends Hilt_ViewModelScopedTest_TestActivity {
63 
64     @Override
onCreate(@ullable Bundle savedInstanceState)65     protected void onCreate(@Nullable Bundle savedInstanceState) {
66       super.onCreate(savedInstanceState);
67       if (savedInstanceState == null) {
68         Fragment f =
69             getSupportFragmentManager()
70                 .getFragmentFactory()
71                 .instantiate(TestFragment.class.getClassLoader(), TestFragment.class.getName());
72         getSupportFragmentManager().beginTransaction().add(0, f, "tag").commitNow();
73       }
74     }
75   }
76 
77   @AndroidEntryPoint(Fragment.class)
78   public static class TestFragment extends Hilt_ViewModelScopedTest_TestFragment {
79     MyViewModel vm;
80 
81     @Override
onCreate(@ullable Bundle bundle)82     public void onCreate(@Nullable Bundle bundle) {
83       super.onCreate(bundle);
84       vm = new ViewModelProvider(this).get(MyViewModel.class);
85     }
86   }
87 
88   @HiltViewModel
89   static class MyViewModel extends ViewModel {
90 
91     final DependsOnBarOne one;
92     final DependsOnBarTwo two;
93 
94     @Inject
MyViewModel(DependsOnBarOne one, DependsOnBarTwo two)95     MyViewModel(DependsOnBarOne one, DependsOnBarTwo two) {
96       this.one = one;
97       this.two = two;
98     }
99   }
100 
101   @ViewModelScoped
102   static class Bar {
103     @Inject
Bar()104     Bar() {}
105   }
106 
107   static class DependsOnBarOne {
108     final Bar bar;
109 
110     @Inject
DependsOnBarOne(Bar bar)111     DependsOnBarOne(Bar bar) {
112       this.bar = bar;
113     }
114   }
115 
116   static class DependsOnBarTwo {
117     final Bar bar;
118 
119     @Inject
DependsOnBarTwo(Bar bar)120     DependsOnBarTwo(Bar bar) {
121       this.bar = bar;
122     }
123   }
124 }
125