2015-05-04 89 views
0

我有一個抽象方法checkStatus(),它在Checker.java類中有實現。但是當我在抽象類方法validate()上執行Junit測試用例時,由於缺少Checker.java類中的彈簧依賴關係,因此調用checkStatus()失敗。Junit測試用例對抽象方法失敗

詳情如下。

抽象類:

public abstract class MyAbstractClass 
{ 
    protected abstract boolean checkStatus(); 

    public boolean validate() 
    { 
     //Some code 
     return checkStatus(); 
    } 
} 

實現類:

public class Checker extends MyAbstractClass 
{ 
    @Autowired 
    private StatusHelper helper; 

    public void setHelper(StatusHelper helper){ 
     this.helper = helper; 
    } 

    @Override 
    public boolean checkStatus() throws Exception{ 
     if(null == helper){ 
      throw new Exception("Helper is null"); 
     } 

     return helper.validateStatus(); 
    } 
} 

JUnit測試:

class AbstractClassTest 
{ 
    MyAbstractClass absClass = Mockito.mock(Checker.class, Mockito.CALLS_REAL_METHODS); 

    @Test 
    public void testStatusOfChecker()throws Exception { 
     boolean status = absClass.validate(); 
     assertEquals(status, true); 
    } 
} 

我相信我可以手動注入輔助對象,像下面的

Checker check = mock(Checker.class); 
StatusHelper helper = mock(StatusHelper.class); 
check.setHelper(helper); 

但這裏的問題是,我不能直接注入absClass對象,因爲setHelper()未被繼承。

我可以改爲直接寫測試用例到子類,但我需要這種方法來測試抽象類的validate()方法中的一些其他功能。

有人可以幫助我如何設置輔助對象的子類或有不同的方式來做到這一點在Junit嗎?任何包含相關信息的幫助或鏈接都是非常可觀的。 謝謝,

回答

2

測試抽象類的唯一方法是通過測試一個實現(可能是一個匿名類)。

public class AbstractClassTest { 
    @Test 
    public void testStatusOfChecker() throws Exception { 
    MyAbstractClass object = new MyAbstractClass() { 
     protected boolean checkStatus() { 
     return true; //this is the place to provide the expected value 
     } 
    } 
    boolean status = absClass.validate(); 
    assertEquals(status, true); 
    } 
} 

如果你想測試Checker的實現,那麼你不能嘲笑它。

public class CheckerTest { 
    @Test 
    public void test() { 
    StatusHelper helper = mock(StatusHelper.class); 
    Checker checker = new Checker(); 
    checker.setHelper(helper); 
    when(helper.validate()).thenReturn(true); 
    boolean status = checker.validate(); 
    assertEquals(status, true); 
    } 
} 

順便說一句,我強烈建議使用構造函數注入(請參閱Why field injection is evil)。測試看起來像這樣

public class CheckerTest { 
    @Test 
    public void test() { 
    StatusHelper helper = mock(StatusHelper.class); 
    Checker checker = new Checker(helper); 
    when(helper.validate()).thenReturn(true); 
    boolean status = checker.validate(); 
    assertEquals(status, true); 
    } 
}