vendredi 16 septembre 2016

How can I inject a Mocked object, but add when conditions before the injection

I have got a scenario which almost seems to work. I have a class I am testing, Testable. It has an autowired instance of Object1 and Object2, as so:

 public class Testable {
     @Autowire private Object1 obj1;
     @Autowire private Object2 obj2;

     public Thing doGoodThing() {
         Resulting r = obj1.doSomething(obj2);
         return r.aResult();
     }
 }

I have a test class:

 public class TestingSmarter {
     @Mock private Object1 obj1;
     @Mock private Object2 obj2;

     @InjectMocks
     @Resource
     private Testable t1;

     @Before
     public void init() {
         MockitoAnnotations.initMocks(this);
     }

     @Test
     public void testNow() {
         t1.doGoodThing();
     }

I have to admit that I do not understand why a @Resource was used here instead of an @Autowire. Too many of the annotations seems to almost duplicate other annotations.

If obj1 and obj2 are initializable, then this all works.

But I need to add when() method invocations to one of the objects, Object1.

 public class TestingSmarter {
     @Mock private Object1 obj1;
     @Mock private Object2 obj2;

     @InjectMocks
     @Resource
     private Testable t1;

     @Before
     public void init() {
         MockitoAnnotations.initMocks(this);
         Mockito.when(obj1.some()).thenReturn(aThing);
     }

     @Test
     public void testNow() {
         t1.doGoodThing();
     }

But when the test runs, the call to obj1.some() returns null.

 public class TestingSmarter {
     @Mock private Object1 obj1;
     @Mock private Object2 obj2;

     @InjectMocks
     @Resource
     private Testable t1;

     @Before
     public void init() {
         Mockito.when(obj1.some()).thenReturn(aThing);
         MockitoAnnotations.initMocks(this);
     }

     @Test
     public void testNow() {
         t1.doGoodThing();
     }

Now, when this runs, there is an NPE from the obj1.some() call, because obj1 has not been initialized yet.

But here it is. I need for obj1 and obj2 to be initialized. Then I need to be able to call when() on them. Those objects needs to be injected into Testable. How can I do this?

If I call the initMocks() method first, all the Mock objects get set up and an obj1 that does nothing gets injected into Testable. But if Testable has not been initialized, neither has obj1, so I cannot call a method in it within a when() method call.

What am I not seeing here? It seems simple enough. Is there yet another random, er..., I mean wonderful annotation that will do the job for me?

There may be an answer here already, but I aint seeing it. Thanx much.

Aucun commentaire:

Enregistrer un commentaire