2013-12-15 110 views
3

我嘗試寫一個測試一樣,使用JUnit一個給定的接口,而且不知道該怎麼做:JUnit測試,而無需執行尚未

public interface ShortMessageService { 

    /** 
    * Creates a message. A message is related to a topic 
    * Creates a date for the message 
    * @throws IllegalArgumentException, if the message is longer then 255 characters. 
    * @throws IllegalArgumentException, if the message ist shorter then 10 characters. 
    * @throws IllegalArgumentException, if the user doesn't exist 
    * @throws IllegalArgumentException, if the topic doesn't exist 
    * @throws NullPointerException, if one argument is null. 
    * @param userName 
    * @param message 
    * @return ID of the new created message 
    */ 
    Long createMessage(String userName, String message, String topic); 

    [...] 
} 

我試圖嘲弄後的界面我意識到它根本沒有意義,所以我有點失落。也許有人可以給我一個我可以合作的好方法。我也聽說過有關junit參數化測試,但我不確定這是否是我正在尋找的。

非常感謝!

回答

5

我使用以下模式來編寫針對我的接口API的抽象測試,而沒有任何可用的實現。您可以在AbstractShortMessageServiceTest中編寫您需要的任何測試,而無需在該時間點實施它們。

public abstract class AbstractShortMessageServiceTest 
{ 
    /** 
    * @return A new empty instance of an implementation of FooManager. 
    */ 
    protected abstract ShortMessageService getNewShortMessageService(); 

    private ShortMessageService testService; 

    @Before 
    public void setUp() throws Exception 
    { 
     testService = getNewShortMessageService(); 
    } 

    @Test 
    public void testFooBar() throws Exception 
    { 
     assertEquals("question", testService.createMessage(
              "DeepThought", "42", "everything")); 
    } 
} 

當你有一個實現,你可以簡單地通過定義一個新的測試類中的覆蓋AbstractShortMessageServiceTest並實現getNewShortMessageService方法使用測試。

public class MyShortMessageServiceTest extends AbstractShortMessageServiceTest 
{ 
    protected ShortMessageService getNewShortMessageService() 
    { 
     return new MyShortMessageService(); 
    } 
} 

另外,如果你需要測試的參數設定,你可以做,在AbstractShortMessageServiceTest無需在每個具體的測試做。

+0

這聽起來像是我的測試用例的完美解決方案/模式,非常感謝! – chillyistkult

+0

@ Chilly90 - 別忘了接受答案,如果您發表評論表明您認爲有用,則可能會對其進行投票。 – EJK

0

通常測試是爲類實現接口和模擬用於協作類,但您可以通過模擬測試您的測試,如果類尚未準備好。這是不尋常的,你應該與可能的情況下實現的邏輯中使用thenAnsfer:

更好的方法是簡單地實現類準備測試,並開始改進它,直到所有測試通過: 實現類可以在現場和測試之前初始化

private ShortMessageService testedClasOrMock; 

//version with implementing class 
@Before 
public void setUp(){ 
     testedClasOrMock = new ShortMessageServiceImpl0(); 
} 

@Before 
public void setUp(){ 
    testedClasOrMock = mock(ShortMessageService.class); 
    when(testedClasOrMock).thenAnswer(new Answer<Long>(){ 

     @Override 
     public Long answer(InvocationOnMock invocation) throws Throwable { 
      String message =(String) invocation.getArguments()[1]; 
      if (message.length() > 256){ 
       throw new IllegalArgumentException("msg is too long"); 
      } 
          //other exception throwing cases 
          …... 
      return new Long(44); 
     }}); 
} 

所以你有幾個測試預計例外像

@Test (expected= IllegalArgumentException.class) 
public void testTooLongMsg(){ 
    testedClasOrMock.createMessage(USER, TOO_LONG_MSG, TOPIC); 
} 

和一個根本不應該拋出異常,例如檢查味精ID不同

@Test 
public void testTooLongMsg(){ 
    long id0 = testedClasOrMock.createMessage(USER, TOO_LONG_MSG, TOPIC); 
    long id1 = testedClasOrMock.createMessage(USER, TOO_LONG_MSG, TOPIC); 
    assertTrue(id0 != id1); 
} 

如果您堅持通過模擬測試您的測試,請告訴我,我將爲一個測試用例添加示例。

+0

謝謝!有更通用的方法嗎?也許我可以開發一個測試,自動測試給定接口的所有實現,而無需在測試過程中對它們進行顯式初始化,因爲對於一個接口可能會有更多的實現,我不想重複自己。像一個魔術junit黑匣子,爲我處理這種情況? 無論如何,我真的對模擬方法的測試感興趣,以加深我的知識。 – chillyistkult

+0

通常(好的)方法是你有一個實現類的測試類。您可以爲ShortMessageService的字段準備通用抽象測試類,並在具體實現類的特定類中實現此字段的初始化,方法是在public void method annotated @Before中,以便在每次測試之前執行。你需要示例還是很清楚? thx – JosefN

+0

我已經爲答案添加了答案示例。希望能幫助到你。 – JosefN

相關問題