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