如何测试任何抛出异常的方法调用?

时间:2015-11-01 06:51:50

标签: java exception junit

JUnit 4.12

我有以下实用方法:

public class StaticFieldsUtils {

    public static <T> T getPublicStaticFieldByName(String name, Class<T> clazz){
        for(Field f : clazz.getDeclaredFields()){
            if(Modifier.isStatic(f.getModifiers()) && 
                 Modifier.isPublic(f.getModifiers()) && 
                 f.getName().equals(name))
                try {
                    Object fieldValue = f.get(null); 
                    if(clazz.isAssignableFrom(fieldValue.getClass()))
                        return (T) fieldValue;
                } catch (IllegalAccessException e) { 
                    throw new IllegalArgumentException(String.format("Invalid access to the field %s", name));
                }
        }
        throw new IllegalArgumentException(String.format("A public field with the name %s does not exist in the class %s", name, clazz.getSimpleName()));
    }

    //Some other utility methods
}

现在,我需要编写测试用例,只有在没有相同类型或其子类型的公共静态字段时才会检查IllegalArgumetnException是否被抛出。

以下是我倾向于写的内容:

public class StaticFieldsUtilsTest {

    private static class StaticFieldContainer{
        public static final StaticFieldContainer FIELD1 = new StaticFieldContainer();
        public static final StaticFieldContainer FIELD2 = new StaticFieldContainer();
        public static final StaticFieldContainer FIELD3 = new StaticFieldContainer();
        public static final StaticFieldContainer FIELD4 = new StaticFieldContainer();
        protected static final StaticFieldContainer FIELD5 = new StaticFieldContainer();
        static final StaticFieldContainer FIELD6 = new StaticFieldContainer();
        private static final StaticFieldContainer FIELD7 = new StaticFieldContainer();
        public static StaticFieldContainer FIELD8 = new StaticFieldContainer();
    }

    @Test(expected=IllegalArgumentException.class)
    public void testViolations(){
        StaticFieldContainer field = StaticFieldsUtils.getPublicStaticFieldByName("FIELD5", StaticFieldContainer.class); 
    }

    @Test(expected=IllegalArgumentException.class)
    public void testViolations2(){
        StaticFieldContainer field = StaticFieldsUtils.getPublicStaticFieldByName("FIELD6", StaticFieldContainer.class); 
    }
    //ETC
}

问题是我无法在单个方法@Test(expected=IllegalArgumentException.class) public void testViolationsX()中可靠地放置多个方法调用,因为我需要检查 每个 调用抛出。

问题: 是否有一些JUnit功能可以避免为任何此类调用编写单个方法来检查它是否会抛出?

2 个答案:

答案 0 :(得分:2)

使用JUnit TheoriesExpectedException规则:

@RunWith(Theories.class)
public class StaticFieldsUtilsTest {

  //your inner class with static fields


  @Rule
  public ExpectedException thrown = ExpectedException.none();

  @DataPoint
  public static String FIELD1 = "Field1";
  @DataPoint
  public static String FIELD2 = "Field2";

  @Theory
  public void testViolations(String field){
    thrown.expect(IllegalArgumentException.class);
    StaticFieldsUtils.getPublicStaticFieldByName(field, StaticFieldContainer.class); 
  }
}

如果您想将许多理论应用于其他名称,我建议您按照here的说明创建自定义注释和ParameterSupplier

答案 1 :(得分:2)

你也可以使用普通的旧for循环:

public void testViolations(){
    for (String fieldName : Arrays.asList("FIELD5", "FIELD6")) {
        try {
            StaticFieldContainer field = StaticFieldsUtils.getPublicStaticFieldByName(fieldName, StaticFieldContainer.class);
            fail();
        } catch (IllegalArgumentException e) {
        }
    }
}