2013-12-15 88 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

相关问题