2 Replies Latest reply on Feb 18, 2011 5:37 AM by Jan Groth

    Unit test that @Produces mock dependencies (avoiding circular dependencies)

    Alistair Israel Newbie

      What I'm basically trying to do is this. I have an interface Dependency, and a class that uses Dependency that I want to test


      class SomeClass {
      
        @Inject
        Dependency dependency;
      }



      I'm trying to write my test like:


      class SomeClassTest {
      
        @Inject
        SomeClass someClass;
      
        @Produces @Mock
        Dependency mockDependency = Mockito.mock(Dependency.class);
      
        @Before
        public void setupWeldSeAndInjectIntoThis() {
          // ...
        }
      
      // ...



      Where @Mock is our very own


      @Alternative
      @Stereotype
      @Retention(RUNTIME)
      @Target({ TYPE, FIELD })
      public @interface Mock




      Am I making sense?


      Except now that debugging/logging shows me that Weld constructs a new instance of SomeClassTest, and in doing so also obtains a new instance of mockDependency. Obviously, that's not what I want it to do.


      Basically, can anyone give me a clue on how to prevent Weld from creating a new instance of the injection target (SomeClassTest), while at the same letting it recognize the @Produces fields/methods in the test?

        • 1. Re: Unit test that @Produces mock dependencies (avoiding circular dependencies)
          Alistair Israel Newbie

          By the way, the avoiding circular dependencies part happens when I try to extract the @Before and @After behavior into a JUnit @Rule.


          That is, if I factor out the WeldSE bootstrap and injection code to another class (a JUnit interceptor), I get the WELD-000018  Executing producer field or method ... on incomplete declaring bean ... due to circular injection warning and a java.util.EmptyStackException


          For the record, my setup code is basically similar to how Weld injection into EJBs is described here:


            WeldContainer weldContainer = weld.initialize();
            BeanManager bm = weldContainer.getBeanManager();
            Class<?> cl = target.getClass();
            AnnotatedType<Object> at = (AnnotatedType<Object>) bm.createAnnotatedType(cl);
            InjectionTarget<Object> it = bm.createInjectionTarget(at);
            CreationalContext<Object> cc = bm.createCreationalContext(null);
            it.inject(target, cc);
          


          Where target is just this in the simple case (in a @Before method), and it's the actual Test instance when it's a JUnit @Rule

          • 2. Re: Unit test that @Produces mock dependencies (avoiding circular dependencies)
            Jan Groth Novice

            Beans which contains producer methods need to be instantiated before producer methods can be executed. That's what happens in your case - so, just separate producer method and test (put it in its own class somewhere on your test classpath). You can also define the scope of mockDependency, in case that DependendtScope is not what you want.


            Cheers,


            Jan