1

I've got three classes A, B and C:

public class A {
  @Autowired
  private B someB;
  private C someC = someB.getSomeC();
}

@Service
public class B {
  C getSomeC() {
    return new C();
  }
}

public class C { }

Now if I write a unit test for A which looks like:

@RunWith(MockitoJUnitRunner.class)
public class ATest {

  @InjectMocks
  private A classUnderTest;

  @Mock
  private B someB;

  @Mock
  private C someC;

  @Test
  public void testSomething() {

  }
}

Mockito is not happy with this:

 org.mockito.exceptions.base.MockitoException: 
    Cannot instantiate @InjectMocks field named 'classUnderTest' of type 'class my.package.A'.
    You haven't provided the instance at field declaration so I tried to construct the instance.
    However the constructor or the initialization block threw an exception : null

If I remove the call in class A, such that class A looks like the following:

public class A {
  private B someB;
  private C someC;
}

, Mockito is able to instantiate the classUnderTest and the test runs through.

Why is this the case?

edit: Using Mockito 1.9.5

ptikobj
  • 2,690
  • 7
  • 39
  • 64

1 Answers1

4

Well this is always going to fail:

public class A {
  private B someB;
  private C someC = someB.getSomeC();
}

You're trying to call getSomeC() on a value which will always be null... that will always thrown NullPointerException. You need to fix A to handle the dependencies better. (Personally I'd take them as constructor parameters, but there are other options of course...)

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • I forgot to add spring annotations, someB is autowired, see above. – ptikobj Dec 12 '13 at 10:30
  • @ptikobj: Well it's not going to be autowired *before the instance variable initializers run* is it? And even if Spring managed to autowire the `someB` field before the `someC` field initializer executed somehow, what makes you think Mockito will be able to perform the same trick? I don't think it's a good idea to have a class where you simply can't call the constructor normally without it throwing an exception... – Jon Skeet Dec 12 '13 at 10:33
  • I wasn't aware of the order of autowiring vs constructor invocation. This is also discussed, e.g. [here](http://stackoverflow.com/questions/6335975/autowired-bean-is-null-when-referenced-in-the-constructor-of-another-bean). – ptikobj Dec 12 '13 at 10:42