2013-12-12 49 views
0

我有三個班ABC類:如果我寫一個單元測試爲A,看起來像的Mockito無法實例測試

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

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

public class C { } 

現在:

@RunWith(MockitoJUnitRunner.class) 
public class ATest { 

    @InjectMocks 
    private A classUnderTest; 

    @Mock 
    private B someB; 

    @Mock 
    private C someC; 

    @Test 
    public void testSomething() { 

    } 
} 

Mockito對此不滿意:

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 

如果我刪除呼叫A類,使得類A如下所示:

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

,是的Mockito能夠實例化classUnderTest和測試貫穿。

爲什麼會出現這種情況?

編輯:使用1.9.5的Mockito

回答

4

嗯,這是總是要失敗:

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

你試圖調用getSomeC()上的值將始終是null ...總是會拋出NullPointerException。您需要修復A以更好地處理依賴關係。 (就我個人而言,我會將它們作爲構造參數,但當然還有其他選項...)

+0

我忘了添加spring註釋,someB是自動裝配的,請參見上文。 – ptikobj

+0

@ptikobj:在實例變量初始化器運行之前,它不會被自動裝入*是嗎?即使Spring設法在'someC'字段初始化器執行之前自動調用'someB'字段,您認爲Mockito能夠執行相同的技巧嗎?我不認爲有一個類,如果沒有拋出異常,你就無法正常調用構造函數,這不是一個好主意...... –

+0

我沒有意識到自動裝配和構造函數調用的順序。這也被討論了,例如[這裏](http://stackoverflow.com/questions/6335975/autowired-bean-is-null-when-referenced-in-the-constructor-of-another-bean)。 – ptikobj