• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2012 Google Inc.
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 com.google.inject;
18 
19 import junit.framework.TestCase;
20 
21 /**
22  * Tests for {@link Binder#requireAtInjectOnConstructors()}
23  *
24  * @author sameb@google.com (Sam Berlin)
25  */
26 public class RequireAtInjectOnConstructorsTest extends TestCase {
27 
testNoCxtors_explicitBinding()28   public void testNoCxtors_explicitBinding() {
29     try {
30       Guice.createInjector(
31           new AbstractModule() {
32             @Override
33             protected void configure() {
34               bind(NoCxtors.class);
35               binder().requireAtInjectOnConstructors();
36             }
37           });
38       fail();
39     } catch (CreationException ce) {
40       assertEquals(1, ce.getErrorMessages().size());
41       Asserts.assertContains(
42           ce.getMessage(),
43           "1) Explicit @Inject annotations are required on constructors, but "
44               + NoCxtors.class.getName()
45               + " has no constructors annotated with @Inject",
46           "at " + RequireAtInjectOnConstructorsTest.class.getName() + "$",
47           "configure");
48     }
49   }
50 
testNoCxtors_jitBinding()51   public void testNoCxtors_jitBinding() {
52     Injector injector =
53         Guice.createInjector(
54             new AbstractModule() {
55               @Override
56               protected void configure() {
57                 binder().requireAtInjectOnConstructors();
58               }
59             });
60     try {
61       injector.getInstance(NoCxtors.class);
62       fail();
63     } catch (ConfigurationException ce) {
64       Asserts.assertContains(
65           ce.getMessage(),
66           "1) Explicit @Inject annotations are required on constructors, but "
67               + NoCxtors.class.getName()
68               + " has no constructors annotated with @Inject",
69           "while locating " + NoCxtors.class.getName());
70     }
71   }
72 
testNoCxtors_implicitBinding()73   public void testNoCxtors_implicitBinding() {
74     try {
75       Guice.createInjector(
76           new AbstractModule() {
77             @Override
78             protected void configure() {
79               bind(Interface.class).to(NoCxtors.class);
80               binder().requireAtInjectOnConstructors();
81             }
82           });
83       fail();
84     } catch (CreationException ce) {
85       assertEquals(1, ce.getErrorMessages().size());
86       Asserts.assertContains(
87           ce.getMessage(),
88           "1) Explicit @Inject annotations are required on constructors, but "
89               + NoCxtors.class.getName()
90               + " has no constructors annotated with @Inject",
91           "at " + RequireAtInjectOnConstructorsTest.class.getName() + "$",
92           "configure");
93     }
94   }
95 
testNoCxtors_inheritedByPrivateModules()96   public void testNoCxtors_inheritedByPrivateModules() {
97     try {
98       Guice.createInjector(
99           new AbstractModule() {
100             @Override
101             protected void configure() {
102               binder().requireAtInjectOnConstructors();
103               install(
104                   new PrivateModule() {
105                     @Override
106                     protected void configure() {
107                       bind(NoCxtors.class);
108                     }
109                   });
110             }
111           });
112       fail();
113     } catch (CreationException ce) {
114       assertEquals(1, ce.getErrorMessages().size());
115       Asserts.assertContains(
116           ce.getMessage(),
117           "1) Explicit @Inject annotations are required on constructors, but "
118               + NoCxtors.class.getName()
119               + " has no constructors annotated with @Inject",
120           "at " + RequireAtInjectOnConstructorsTest.class.getName() + "$",
121           "configure");
122     }
123   }
124 
testNoCxtors_accumulatesAllErrors()125   public void testNoCxtors_accumulatesAllErrors() {
126     try {
127       Guice.createInjector(
128           new AbstractModule() {
129             @Override
130             protected void configure() {
131               bind(NoCxtors.class);
132               bind(AnotherNoCxtors.class);
133               binder().requireAtInjectOnConstructors();
134             }
135           });
136       fail();
137     } catch (CreationException ce) {
138       assertEquals(2, ce.getErrorMessages().size());
139       Asserts.assertContains(
140           ce.getMessage(),
141           "1) Explicit @Inject annotations are required on constructors, but "
142               + NoCxtors.class.getName()
143               + " has no constructors annotated with @Inject",
144           "at " + RequireAtInjectOnConstructorsTest.class.getName() + "$",
145           "configure",
146           "2) Explicit @Inject annotations are required on constructors, but "
147               + AnotherNoCxtors.class.getName()
148               + " has no constructors annotated with @Inject",
149           "at " + RequireAtInjectOnConstructorsTest.class.getName() + "$",
150           "configure");
151     }
152   }
153 
testNoCxtors_separateOptionsForPrivateModules()154   public void testNoCxtors_separateOptionsForPrivateModules() {
155     try {
156       Guice.createInjector(
157           new AbstractModule() {
158             @Override
159             protected void configure() {
160               bind(AnotherNoCxtors.class);
161               install(
162                   new PrivateModule() {
163                     @Override
164                     protected void configure() {
165                       binder().requireAtInjectOnConstructors();
166                       bind(NoCxtors.class);
167                     }
168                   });
169             }
170           });
171       fail();
172     } catch (CreationException ce) {
173       // This is testing that the parent module doesn't fail because it isn't included
174       // in the error message.
175       assertEquals(1, ce.getErrorMessages().size());
176       Asserts.assertContains(
177           ce.getMessage(),
178           "1) Explicit @Inject annotations are required on constructors, but "
179               + NoCxtors.class.getName()
180               + " has no constructors annotated with @Inject",
181           "at " + RequireAtInjectOnConstructorsTest.class.getName() + "$",
182           "configure");
183     }
184   }
185 
testManyConstructorsButNoneWithAtInject()186   public void testManyConstructorsButNoneWithAtInject() {
187     try {
188       Guice.createInjector(
189           new AbstractModule() {
190             @Override
191             protected void configure() {
192               bind(ManyConstructors.class);
193               binder().requireAtInjectOnConstructors();
194             }
195           });
196       fail();
197     } catch (CreationException ce) {
198       assertEquals(1, ce.getErrorMessages().size());
199       Asserts.assertContains(
200           ce.getMessage(),
201           "1) Explicit @Inject annotations are required on constructors, but "
202               + ManyConstructors.class.getName()
203               + " has no constructors annotated with @Inject",
204           "at " + RequireAtInjectOnConstructorsTest.class.getName() + "$",
205           "configure");
206     }
207   }
208 
testRequireAtInjectStillAllowsToConstructorBindings()209   public void testRequireAtInjectStillAllowsToConstructorBindings() {
210     Injector injector =
211         Guice.createInjector(
212             new AbstractModule() {
213               @Override
214               protected void configure() {
215                 try {
216                   bind(ManyConstructors.class)
217                       .toConstructor(ManyConstructors.class.getDeclaredConstructor());
218                 } catch (Exception e) {
219                   throw new RuntimeException(e);
220                 }
221                 binder().requireAtInjectOnConstructors();
222               }
223             });
224     injector.getInstance(ManyConstructors.class);
225   }
226 
227   private static interface Interface {}
228 
229   private static class NoCxtors implements Interface {}
230 
231   private static class AnotherNoCxtors {}
232 
233   private static class ManyConstructors {
234     @SuppressWarnings("unused")
ManyConstructors()235     ManyConstructors() {}
236 
237     @SuppressWarnings("unused")
ManyConstructors(String a)238     ManyConstructors(String a) {}
239 
240     @SuppressWarnings("unused")
ManyConstructors(int a)241     ManyConstructors(int a) {}
242   }
243 }
244