1 /* 2 * Copyright (C) 2009 The JSR-330 Expert Group 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 org.atinject.tck.auto; 18 19 import junit.framework.TestCase; 20 import org.atinject.tck.auto.accessories.Cupholder; 21 import org.atinject.tck.auto.accessories.SpareTire; 22 import org.atinject.tck.auto.accessories.RoundThing; 23 24 import javax.inject.Inject; 25 import javax.inject.Named; 26 import javax.inject.Provider; 27 28 public class Convertible implements Car { 29 30 @Inject @Drivers Seat driversSeatA; 31 @Inject @Drivers Seat driversSeatB; 32 @Inject SpareTire spareTire; 33 @Inject Cupholder cupholder; 34 @Inject Provider<Engine> engineProvider; 35 36 private boolean methodWithZeroParamsInjected; 37 private boolean methodWithMultipleParamsInjected; 38 private boolean methodWithNonVoidReturnInjected; 39 40 private Seat constructorPlainSeat; 41 private Seat constructorDriversSeat; 42 private Tire constructorPlainTire; 43 private Tire constructorSpareTire; 44 private Provider<Seat> constructorPlainSeatProvider = nullProvider(); 45 private Provider<Seat> constructorDriversSeatProvider = nullProvider(); 46 private Provider<Tire> constructorPlainTireProvider = nullProvider(); 47 private Provider<Tire> constructorSpareTireProvider = nullProvider(); 48 49 @Inject Seat fieldPlainSeat; 50 @Inject @Drivers Seat fieldDriversSeat; 51 @Inject Tire fieldPlainTire; 52 @Inject @Named("spare") Tire fieldSpareTire; 53 @Inject Provider<Seat> fieldPlainSeatProvider = nullProvider(); 54 @Inject @Drivers Provider<Seat> fieldDriversSeatProvider = nullProvider(); 55 @Inject Provider<Tire> fieldPlainTireProvider = nullProvider(); 56 @Inject @Named("spare") Provider<Tire> fieldSpareTireProvider = nullProvider(); 57 58 private Seat methodPlainSeat; 59 private Seat methodDriversSeat; 60 private Tire methodPlainTire; 61 private Tire methodSpareTire; 62 private Provider<Seat> methodPlainSeatProvider = nullProvider(); 63 private Provider<Seat> methodDriversSeatProvider = nullProvider(); 64 private Provider<Tire> methodPlainTireProvider = nullProvider(); 65 private Provider<Tire> methodSpareTireProvider = nullProvider(); 66 67 @Inject static Seat staticFieldPlainSeat; 68 @Inject @Drivers static Seat staticFieldDriversSeat; 69 @Inject static Tire staticFieldPlainTire; 70 @Inject @Named("spare") static Tire staticFieldSpareTire; 71 @Inject static Provider<Seat> staticFieldPlainSeatProvider = nullProvider(); 72 @Inject @Drivers static Provider<Seat> staticFieldDriversSeatProvider = nullProvider(); 73 @Inject static Provider<Tire> staticFieldPlainTireProvider = nullProvider(); 74 @Inject @Named("spare") static Provider<Tire> staticFieldSpareTireProvider = nullProvider(); 75 76 private static Seat staticMethodPlainSeat; 77 private static Seat staticMethodDriversSeat; 78 private static Tire staticMethodPlainTire; 79 private static Tire staticMethodSpareTire; 80 private static Provider<Seat> staticMethodPlainSeatProvider = nullProvider(); 81 private static Provider<Seat> staticMethodDriversSeatProvider = nullProvider(); 82 private static Provider<Tire> staticMethodPlainTireProvider = nullProvider(); 83 private static Provider<Tire> staticMethodSpareTireProvider = nullProvider(); 84 Convertible( Seat plainSeat, @Drivers Seat driversSeat, Tire plainTire, @Named("spare") Tire spareTire, Provider<Seat> plainSeatProvider, @Drivers Provider<Seat> driversSeatProvider, Provider<Tire> plainTireProvider, @Named("spare") Provider<Tire> spareTireProvider)85 @Inject Convertible( 86 Seat plainSeat, 87 @Drivers Seat driversSeat, 88 Tire plainTire, 89 @Named("spare") Tire spareTire, 90 Provider<Seat> plainSeatProvider, 91 @Drivers Provider<Seat> driversSeatProvider, 92 Provider<Tire> plainTireProvider, 93 @Named("spare") Provider<Tire> spareTireProvider) { 94 constructorPlainSeat = plainSeat; 95 constructorDriversSeat = driversSeat; 96 constructorPlainTire = plainTire; 97 constructorSpareTire = spareTire; 98 constructorPlainSeatProvider = plainSeatProvider; 99 constructorDriversSeatProvider = driversSeatProvider; 100 constructorPlainTireProvider = plainTireProvider; 101 constructorSpareTireProvider = spareTireProvider; 102 } 103 Convertible()104 Convertible() { 105 throw new AssertionError("Unexpected call to non-injectable constructor"); 106 } 107 setSeat(Seat unused)108 void setSeat(Seat unused) { 109 throw new AssertionError("Unexpected call to non-injectable method"); 110 } 111 injectMethodWithZeroArgs()112 @Inject void injectMethodWithZeroArgs() { 113 methodWithZeroParamsInjected = true; 114 } 115 injectMethodWithNonVoidReturn()116 @Inject String injectMethodWithNonVoidReturn() { 117 methodWithNonVoidReturnInjected = true; 118 return "unused"; 119 } 120 injectInstanceMethodWithManyArgs( Seat plainSeat, @Drivers Seat driversSeat, Tire plainTire, @Named("spare") Tire spareTire, Provider<Seat> plainSeatProvider, @Drivers Provider<Seat> driversSeatProvider, Provider<Tire> plainTireProvider, @Named("spare") Provider<Tire> spareTireProvider)121 @Inject void injectInstanceMethodWithManyArgs( 122 Seat plainSeat, 123 @Drivers Seat driversSeat, 124 Tire plainTire, 125 @Named("spare") Tire spareTire, 126 Provider<Seat> plainSeatProvider, 127 @Drivers Provider<Seat> driversSeatProvider, 128 Provider<Tire> plainTireProvider, 129 @Named("spare") Provider<Tire> spareTireProvider) { 130 methodWithMultipleParamsInjected = true; 131 132 methodPlainSeat = plainSeat; 133 methodDriversSeat = driversSeat; 134 methodPlainTire = plainTire; 135 methodSpareTire = spareTire; 136 methodPlainSeatProvider = plainSeatProvider; 137 methodDriversSeatProvider = driversSeatProvider; 138 methodPlainTireProvider = plainTireProvider; 139 methodSpareTireProvider = spareTireProvider; 140 } 141 injectStaticMethodWithManyArgs( Seat plainSeat, @Drivers Seat driversSeat, Tire plainTire, @Named("spare") Tire spareTire, Provider<Seat> plainSeatProvider, @Drivers Provider<Seat> driversSeatProvider, Provider<Tire> plainTireProvider, @Named("spare") Provider<Tire> spareTireProvider)142 @Inject static void injectStaticMethodWithManyArgs( 143 Seat plainSeat, 144 @Drivers Seat driversSeat, 145 Tire plainTire, 146 @Named("spare") Tire spareTire, 147 Provider<Seat> plainSeatProvider, 148 @Drivers Provider<Seat> driversSeatProvider, 149 Provider<Tire> plainTireProvider, 150 @Named("spare") Provider<Tire> spareTireProvider) { 151 staticMethodPlainSeat = plainSeat; 152 staticMethodDriversSeat = driversSeat; 153 staticMethodPlainTire = plainTire; 154 staticMethodSpareTire = spareTire; 155 staticMethodPlainSeatProvider = plainSeatProvider; 156 staticMethodDriversSeatProvider = driversSeatProvider; 157 staticMethodPlainTireProvider = plainTireProvider; 158 staticMethodSpareTireProvider = spareTireProvider; 159 } 160 161 /** 162 * Returns a provider that always returns null. This is used as a default 163 * value to avoid null checks for omitted provider injections. 164 */ nullProvider()165 private static <T> Provider<T> nullProvider() { 166 return new Provider<T>() { 167 public T get() { 168 return null; 169 } 170 }; 171 } 172 173 public static ThreadLocal<Convertible> localConvertible 174 = new ThreadLocal<Convertible>(); 175 176 public static class Tests extends TestCase { 177 178 private final Convertible car = localConvertible.get(); 179 private final Cupholder cupholder = car.cupholder; 180 private final SpareTire spareTire = car.spareTire; 181 private final Tire plainTire = car.fieldPlainTire; 182 private final Engine engine = car.engineProvider.get(); 183 184 // smoke tests: if these fail all bets are off 185 186 public void testFieldsInjected() { 187 assertTrue(cupholder != null && spareTire != null); 188 } 189 190 public void testProviderReturnedValues() { 191 assertTrue(engine != null); 192 } 193 194 // injecting different kinds of members 195 196 public void testMethodWithZeroParametersInjected() { 197 assertTrue(car.methodWithZeroParamsInjected); 198 } 199 200 public void testMethodWithMultipleParametersInjected() { 201 assertTrue(car.methodWithMultipleParamsInjected); 202 } 203 204 public void testNonVoidMethodInjected() { 205 assertTrue(car.methodWithNonVoidReturnInjected); 206 } 207 208 public void testPublicNoArgsConstructorInjected() { 209 assertTrue(engine.publicNoArgsConstructorInjected); 210 } 211 212 public void testSubtypeFieldsInjected() { 213 assertTrue(spareTire.hasSpareTireBeenFieldInjected()); 214 } 215 216 public void testSubtypeMethodsInjected() { 217 assertTrue(spareTire.hasSpareTireBeenMethodInjected()); 218 } 219 220 public void testSupertypeFieldsInjected() { 221 assertTrue(spareTire.hasTireBeenFieldInjected()); 222 } 223 224 public void testSupertypeMethodsInjected() { 225 assertTrue(spareTire.hasTireBeenMethodInjected()); 226 } 227 228 public void testTwiceOverriddenMethodInjectedWhenMiddleLacksAnnotation() { 229 assertTrue(engine.overriddenTwiceWithOmissionInMiddleInjected); 230 } 231 232 // injected values 233 234 public void testQualifiersNotInheritedFromOverriddenMethod() { 235 assertFalse(engine.qualifiersInheritedFromOverriddenMethod); 236 } 237 238 public void testConstructorInjectionWithValues() { 239 assertFalse("Expected unqualified value", 240 car.constructorPlainSeat instanceof DriversSeat); 241 assertFalse("Expected unqualified value", 242 car.constructorPlainTire instanceof SpareTire); 243 assertTrue("Expected qualified value", 244 car.constructorDriversSeat instanceof DriversSeat); 245 assertTrue("Expected qualified value", 246 car.constructorSpareTire instanceof SpareTire); 247 } 248 249 public void testFieldInjectionWithValues() { 250 assertFalse("Expected unqualified value", 251 car.fieldPlainSeat instanceof DriversSeat); 252 assertFalse("Expected unqualified value", 253 car.fieldPlainTire instanceof SpareTire); 254 assertTrue("Expected qualified value", 255 car.fieldDriversSeat instanceof DriversSeat); 256 assertTrue("Expected qualified value", 257 car.fieldSpareTire instanceof SpareTire); 258 } 259 260 public void testMethodInjectionWithValues() { 261 assertFalse("Expected unqualified value", 262 car.methodPlainSeat instanceof DriversSeat); 263 assertFalse("Expected unqualified value", 264 car.methodPlainTire instanceof SpareTire); 265 assertTrue("Expected qualified value", 266 car.methodDriversSeat instanceof DriversSeat); 267 assertTrue("Expected qualified value", 268 car.methodSpareTire instanceof SpareTire); 269 } 270 271 // injected providers 272 273 public void testConstructorInjectionWithProviders() { 274 assertFalse("Expected unqualified value", 275 car.constructorPlainSeatProvider.get() instanceof DriversSeat); 276 assertFalse("Expected unqualified value", 277 car.constructorPlainTireProvider.get() instanceof SpareTire); 278 assertTrue("Expected qualified value", 279 car.constructorDriversSeatProvider.get() instanceof DriversSeat); 280 assertTrue("Expected qualified value", 281 car.constructorSpareTireProvider.get() instanceof SpareTire); 282 } 283 284 public void testFieldInjectionWithProviders() { 285 assertFalse("Expected unqualified value", 286 car.fieldPlainSeatProvider.get() instanceof DriversSeat); 287 assertFalse("Expected unqualified value", 288 car.fieldPlainTireProvider.get() instanceof SpareTire); 289 assertTrue("Expected qualified value", 290 car.fieldDriversSeatProvider.get() instanceof DriversSeat); 291 assertTrue("Expected qualified value", 292 car.fieldSpareTireProvider.get() instanceof SpareTire); 293 } 294 295 public void testMethodInjectionWithProviders() { 296 assertFalse("Expected unqualified value", 297 car.methodPlainSeatProvider.get() instanceof DriversSeat); 298 assertFalse("Expected unqualified value", 299 car.methodPlainTireProvider.get() instanceof SpareTire); 300 assertTrue("Expected qualified value", 301 car.methodDriversSeatProvider.get() instanceof DriversSeat); 302 assertTrue("Expected qualified value", 303 car.methodSpareTireProvider.get() instanceof SpareTire); 304 } 305 306 307 // singletons 308 309 public void testConstructorInjectedProviderYieldsSingleton() { 310 assertSame("Expected same value", 311 car.constructorPlainSeatProvider.get(), car.constructorPlainSeatProvider.get()); 312 } 313 314 public void testFieldInjectedProviderYieldsSingleton() { 315 assertSame("Expected same value", 316 car.fieldPlainSeatProvider.get(), car.fieldPlainSeatProvider.get()); 317 } 318 319 public void testMethodInjectedProviderYieldsSingleton() { 320 assertSame("Expected same value", 321 car.methodPlainSeatProvider.get(), car.methodPlainSeatProvider.get()); 322 } 323 324 public void testCircularlyDependentSingletons() { 325 // uses provider.get() to get around circular deps 326 assertSame(cupholder.seatProvider.get().getCupholder(), cupholder); 327 } 328 329 330 // non singletons 331 332 public void testSingletonAnnotationNotInheritedFromSupertype() { 333 assertNotSame(car.driversSeatA, car.driversSeatB); 334 } 335 336 public void testConstructorInjectedProviderYieldsDistinctValues() { 337 assertNotSame("Expected distinct values", 338 car.constructorDriversSeatProvider.get(), car.constructorDriversSeatProvider.get()); 339 assertNotSame("Expected distinct values", 340 car.constructorPlainTireProvider.get(), car.constructorPlainTireProvider.get()); 341 assertNotSame("Expected distinct values", 342 car.constructorSpareTireProvider.get(), car.constructorSpareTireProvider.get()); 343 } 344 345 public void testFieldInjectedProviderYieldsDistinctValues() { 346 assertNotSame("Expected distinct values", 347 car.fieldDriversSeatProvider.get(), car.fieldDriversSeatProvider.get()); 348 assertNotSame("Expected distinct values", 349 car.fieldPlainTireProvider.get(), car.fieldPlainTireProvider.get()); 350 assertNotSame("Expected distinct values", 351 car.fieldSpareTireProvider.get(), car.fieldSpareTireProvider.get()); 352 } 353 354 public void testMethodInjectedProviderYieldsDistinctValues() { 355 assertNotSame("Expected distinct values", 356 car.methodDriversSeatProvider.get(), car.methodDriversSeatProvider.get()); 357 assertNotSame("Expected distinct values", 358 car.methodPlainTireProvider.get(), car.methodPlainTireProvider.get()); 359 assertNotSame("Expected distinct values", 360 car.methodSpareTireProvider.get(), car.methodSpareTireProvider.get()); 361 } 362 363 364 // mix inheritance + visibility 365 366 public void testPackagePrivateMethodInjectedDifferentPackages() { 367 assertTrue(spareTire.subPackagePrivateMethodInjected); 368 assertTrue(spareTire.superPackagePrivateMethodInjected); 369 } 370 371 public void testOverriddenProtectedMethodInjection() { 372 assertTrue(spareTire.subProtectedMethodInjected); 373 assertFalse(spareTire.superProtectedMethodInjected); 374 } 375 376 public void testOverriddenPublicMethodNotInjected() { 377 assertTrue(spareTire.subPublicMethodInjected); 378 assertFalse(spareTire.superPublicMethodInjected); 379 } 380 381 382 // inject in order 383 384 public void testFieldsInjectedBeforeMethods() { 385 assertFalse(spareTire.methodInjectedBeforeFields); 386 } 387 388 public void testSupertypeMethodsInjectedBeforeSubtypeFields() { 389 assertFalse(spareTire.subtypeFieldInjectedBeforeSupertypeMethods); 390 } 391 392 public void testSupertypeMethodInjectedBeforeSubtypeMethods() { 393 assertFalse(spareTire.subtypeMethodInjectedBeforeSupertypeMethods); 394 } 395 396 397 // necessary injections occur 398 399 public void testPackagePrivateMethodInjectedEvenWhenSimilarMethodLacksAnnotation() { 400 assertTrue(spareTire.subPackagePrivateMethodForOverrideInjected); 401 } 402 403 404 // override or similar method without @Inject 405 406 public void testPrivateMethodNotInjectedWhenSupertypeHasAnnotatedSimilarMethod() { 407 assertFalse(spareTire.superPrivateMethodForOverrideInjected); 408 } 409 410 public void testPackagePrivateMethodNotInjectedWhenOverrideLacksAnnotation() { 411 assertFalse(engine.subPackagePrivateMethodForOverrideInjected); 412 assertFalse(engine.superPackagePrivateMethodForOverrideInjected); 413 } 414 415 public void testPackagePrivateMethodNotInjectedWhenSupertypeHasAnnotatedSimilarMethod() { 416 assertFalse(spareTire.superPackagePrivateMethodForOverrideInjected); 417 } 418 419 public void testProtectedMethodNotInjectedWhenOverrideNotAnnotated() { 420 assertFalse(spareTire.protectedMethodForOverrideInjected); 421 } 422 423 public void testPublicMethodNotInjectedWhenOverrideNotAnnotated() { 424 assertFalse(spareTire.publicMethodForOverrideInjected); 425 } 426 427 public void testTwiceOverriddenMethodNotInjectedWhenOverrideLacksAnnotation() { 428 assertFalse(engine.overriddenTwiceWithOmissionInSubclassInjected); 429 } 430 431 public void testOverriddingMixedWithPackagePrivate2() { 432 assertTrue(spareTire.packagePrivateMethod2Injected); 433 assertTrue(((Tire) spareTire).packagePrivateMethod2Injected); 434 assertFalse(((RoundThing) spareTire).packagePrivateMethod2Injected); 435 436 assertTrue(plainTire.packagePrivateMethod2Injected); 437 assertTrue(((RoundThing) plainTire).packagePrivateMethod2Injected); 438 } 439 440 public void testOverriddingMixedWithPackagePrivate3() { 441 assertFalse(spareTire.packagePrivateMethod3Injected); 442 assertTrue(((Tire) spareTire).packagePrivateMethod3Injected); 443 assertFalse(((RoundThing) spareTire).packagePrivateMethod3Injected); 444 445 assertTrue(plainTire.packagePrivateMethod3Injected); 446 assertTrue(((RoundThing) plainTire).packagePrivateMethod3Injected); 447 } 448 449 public void testOverriddingMixedWithPackagePrivate4() { 450 assertFalse(plainTire.packagePrivateMethod4Injected); 451 assertTrue(((RoundThing) plainTire).packagePrivateMethod4Injected); 452 } 453 454 // inject only once 455 456 public void testOverriddenPackagePrivateMethodInjectedOnlyOnce() { 457 assertFalse(engine.overriddenPackagePrivateMethodInjectedTwice); 458 } 459 460 public void testSimilarPackagePrivateMethodInjectedOnlyOnce() { 461 assertFalse(spareTire.similarPackagePrivateMethodInjectedTwice); 462 } 463 464 public void testOverriddenProtectedMethodInjectedOnlyOnce() { 465 assertFalse(spareTire.overriddenProtectedMethodInjectedTwice); 466 } 467 468 public void testOverriddenPublicMethodInjectedOnlyOnce() { 469 assertFalse(spareTire.overriddenPublicMethodInjectedTwice); 470 } 471 472 } 473 474 public static class StaticTests extends TestCase { 475 476 public void testSubtypeStaticFieldsInjected() { 477 assertTrue(SpareTire.hasBeenStaticFieldInjected()); 478 } 479 480 public void testSubtypeStaticMethodsInjected() { 481 assertTrue(SpareTire.hasBeenStaticMethodInjected()); 482 } 483 484 public void testSupertypeStaticFieldsInjected() { 485 assertTrue(Tire.hasBeenStaticFieldInjected()); 486 } 487 488 public void testSupertypeStaticMethodsInjected() { 489 assertTrue(Tire.hasBeenStaticMethodInjected()); 490 } 491 492 public void testStaticFieldInjectionWithValues() { 493 assertFalse("Expected unqualified value", 494 staticFieldPlainSeat instanceof DriversSeat); 495 assertFalse("Expected unqualified value", 496 staticFieldPlainTire instanceof SpareTire); 497 assertTrue("Expected qualified value", 498 staticFieldDriversSeat instanceof DriversSeat); 499 assertTrue("Expected qualified value", 500 staticFieldSpareTire instanceof SpareTire); 501 } 502 503 public void testStaticMethodInjectionWithValues() { 504 assertFalse("Expected unqualified value", 505 staticMethodPlainSeat instanceof DriversSeat); 506 assertFalse("Expected unqualified value", 507 staticMethodPlainTire instanceof SpareTire); 508 assertTrue("Expected qualified value", 509 staticMethodDriversSeat instanceof DriversSeat); 510 assertTrue("Expected qualified value", 511 staticMethodSpareTire instanceof SpareTire); 512 } 513 514 public void testStaticFieldsInjectedBeforeMethods() { 515 assertFalse(SpareTire.staticMethodInjectedBeforeStaticFields); 516 } 517 518 public void testSupertypeStaticMethodsInjectedBeforeSubtypeStaticFields() { 519 assertFalse(SpareTire.subtypeStaticFieldInjectedBeforeSupertypeStaticMethods); 520 } 521 522 public void testSupertypeStaticMethodsInjectedBeforeSubtypeStaticMethods() { 523 assertFalse(SpareTire.subtypeStaticMethodInjectedBeforeSupertypeStaticMethods); 524 } 525 526 public void testStaticFieldInjectionWithProviders() { 527 assertFalse("Expected unqualified value", 528 staticFieldPlainSeatProvider.get() instanceof DriversSeat); 529 assertFalse("Expected unqualified value", 530 staticFieldPlainTireProvider.get() instanceof SpareTire); 531 assertTrue("Expected qualified value", 532 staticFieldDriversSeatProvider.get() instanceof DriversSeat); 533 assertTrue("Expected qualified value", 534 staticFieldSpareTireProvider.get() instanceof SpareTire); 535 } 536 537 public void testStaticMethodInjectionWithProviders() { 538 assertFalse("Expected unqualified value", 539 staticMethodPlainSeatProvider.get() instanceof DriversSeat); 540 assertFalse("Expected unqualified value", 541 staticMethodPlainTireProvider.get() instanceof SpareTire); 542 assertTrue("Expected qualified value", 543 staticMethodDriversSeatProvider.get() instanceof DriversSeat); 544 assertTrue("Expected qualified value", 545 staticMethodSpareTireProvider.get() instanceof SpareTire); 546 } 547 } 548 549 public static class PrivateTests extends TestCase { 550 551 private final Convertible car = localConvertible.get(); 552 private final Engine engine = car.engineProvider.get(); 553 private final SpareTire spareTire = car.spareTire; 554 555 public void testSupertypePrivateMethodInjected() { 556 assertTrue(spareTire.superPrivateMethodInjected); 557 assertTrue(spareTire.subPrivateMethodInjected); 558 } 559 560 public void testPackagePrivateMethodInjectedSamePackage() { 561 assertTrue(engine.subPackagePrivateMethodInjected); 562 assertFalse(engine.superPackagePrivateMethodInjected); 563 } 564 565 public void testPrivateMethodInjectedEvenWhenSimilarMethodLacksAnnotation() { 566 assertTrue(spareTire.subPrivateMethodForOverrideInjected); 567 } 568 569 public void testSimilarPrivateMethodInjectedOnlyOnce() { 570 assertFalse(spareTire.similarPrivateMethodInjectedTwice); 571 } 572 } 573 } 574