1 /* 2 * Copyright (C) 2006 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 java.util.concurrent.CountDownLatch; 20 import java.util.concurrent.atomic.AtomicReference; 21 import junit.framework.TestCase; 22 23 /** @author jessewilson@google.com (Jesse Wilson) */ 24 25 public class BindingOrderTest extends TestCase { 26 testBindingOutOfOrder()27 public void testBindingOutOfOrder() { 28 Guice.createInjector( 29 new AbstractModule() { 30 @Override 31 protected void configure() { 32 bind(BoundFirst.class); 33 bind(BoundSecond.class).to(BoundSecondImpl.class); 34 } 35 }); 36 } 37 38 public static class BoundFirst { 39 @Inject BoundFirst(BoundSecond boundSecond)40 public BoundFirst(BoundSecond boundSecond) {} 41 } 42 43 interface BoundSecond {} 44 45 static class BoundSecondImpl implements BoundSecond {} 46 testBindingOrderAndScopes()47 public void testBindingOrderAndScopes() { 48 Injector injector = 49 Guice.createInjector( 50 new AbstractModule() { 51 @Override 52 protected void configure() { 53 bind(A.class); 54 bind(B.class).asEagerSingleton(); 55 } 56 }); 57 58 assertSame(injector.getInstance(A.class).b, injector.getInstance(A.class).b); 59 } 60 testBindingWithExtraThreads()61 public void testBindingWithExtraThreads() throws InterruptedException { 62 final CountDownLatch ready = new CountDownLatch(1); 63 final CountDownLatch done = new CountDownLatch(1); 64 final AtomicReference<B> ref = new AtomicReference<>(); 65 66 final Object createsAThread = 67 new Object() { 68 @Inject 69 void createAnotherThread(final Injector injector) { 70 new Thread() { 71 @Override 72 public void run() { 73 ready.countDown(); 74 A a = injector.getInstance(A.class); 75 ref.set(a.b); 76 done.countDown(); 77 } 78 }.start(); 79 80 // to encourage collisions, we make sure the other thread is running before returning 81 try { 82 ready.await(); 83 } catch (InterruptedException e) { 84 throw new RuntimeException(e); 85 } 86 } 87 }; 88 89 Guice.createInjector( 90 new AbstractModule() { 91 @Override 92 protected void configure() { 93 requestInjection(createsAThread); 94 bind(A.class).toInstance(new A()); 95 } 96 }); 97 98 done.await(); 99 assertNotNull(ref.get()); 100 } 101 102 static class A { 103 @Inject B b; 104 } 105 106 static class B {} 107 } 108