Junit在循环中处理预期的异常

时间:2014-03-02 14:21:18

标签: java for-loop exception-handling junit

我已经学会了如何在Junit测试中捕获异常。但现在我想循环遍历参数,这些参数可能导致异常{null, Object.class}当前第一个循环的测试运行然后存在传递而不检查下一个循环参数。

@Rule
public ExpectedException ee;

public ClassTest() {
    this.ee = ExpectedException.none();
}

/**
 * Test of isCompramised method.
 */
@Test
public void testIsCompramised2() {
    System.out.println("isCompramised Exception");
    Class<?>[] c = {null, Object.class};
    for (Class<?> class1 : c) {
        MyClass instance = new MyClass();

        ee.expect(IllegalArgumentException.class);
        boolean result = instance.isCompramised(class1);
        fail("Exception should have been thrown");

    }
}

所以我尝试了这个,它完成了for循环但是所有预期的异常都失败了,因为我认为Try Catch现在可以窃取异常。

/**
 * Test of isCompramised method, of class MyClass.
 */
@Test
public void testIsCompramised2() {
    System.out.println("isCompramised Exception");
    Class<?>[] c = {null, Object.class};
    for (Class<?> class1 : c) {
        MyClass instance = new MyClass();
        try{
            ee.expect(IllegalArgumentException.class);
            boolean result = instance.isCompramised(class1);
            fail("Exception should have been thrown");
        } catch (Exception e){
            continue;
        }
    }
}

建议吗?

这是对的吗?

try{     
    boolean result = instance.isCompramised(class1);
    fail("Exception should have been thrown");
} catch (Exception e){
    AssertTrue(e instanceOf IllegalArgumentException);
    continue;
}

3 个答案:

答案 0 :(得分:3)

我会选择类似的东西:

import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.junit.runners.Parameterized.Parameter;
import org.junit.runners.Parameterized.Parameters;

import java.util.Arrays;


@RunWith(Parameterized.class)
public class Foo {

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

    @Parameter
    public Class<?> input;

    /**
     * Test of isCompramised method, of class MyClass.
     */
    @Test
    public void testIsCompramised() {
        this.expectedException.expect(IllegalArgumentException.class);
        final MyClass instance = new MyClass();
        instance.isCompramised(input);
    }

    @Parameters(name = "test for {0}")
    public static Iterable<Object[]> data() {
        return Arrays.asList(new Object[][] { {null}, {Object.class} });
    }
}

(或两种测试方法,一种用于null,另一种用于Object


编辑:一些补充(见评论)

使用@Parameters注释的方法会返回包含Iterable的{​​{1}}。这些Object[]中的每一个都绑定到Object[]带注释的字段(使用@Parameter的值作为索引[default:0])。 JUnit @Parameter运行器将迭代Parameterized数据,并为每个数组设置字段值,然后运行类中的每个测试。

另请参阅:Parameterized javadoc

答案 1 :(得分:0)

在循环中手动捕获和检查异常,而不是使用expect,可能是去那里的方法。如果放在循环中,那么“这是正确的”代码块应该有效。

答案 2 :(得分:0)

因为这是搜索时我想添加解决方案的第一个google结果。

在我的示例中,如果日期在构造函数中获得无效参数,则Datum会抛出异常。

为了测试这个,我想测试构造函数不会接受无效输入并抛出异常。

我测试了一系列应该用for循环拒绝的示例案例。

为了测试循环在每次迭代中引发异常,我只是添加了一个布尔变量,如果在迭代结束时该变量为false,则在每次迭代时在catch中设置为true,然后运行时异常将被抛出,让测试失败。

我认为这对团队成员来说更容易阅读,而且没有任何关于junit测试的奢侈知识。 对初学者来说也更容易使用。

package übungen.blatt_01;

import org.junit.Test;

public class DatumTest {

@Test
public void testConstructor() throws Exception {
    for(int jahr = 1801; jahr <2010; jahr++) {
        for(int monat = 1; monat <= 12; monat++) {
            for(int tag = 1; tag <= Datum.getMonatslänge(monat, jahr); tag++) {
                try{
                    new Datum(tag,monat,jahr);
                }
                catch(Exception e){System.out.println(tag+","+monat+","+jahr); e.printStackTrace(); return;}
            }
        }
    }
}

@Test
public void testAllExclusive() {
    boolean failAsExpected = false;
    for(int jahr = 1801; jahr <2010; jahr++) {
        for(int monat = 12+1; monat <= 24; monat++) {
            for(int tag = 32; tag <= 60; tag++) {
                failAsExpected=false;
                try {
                    testConstructorErrors(tag,monat,jahr);
                }catch(DateOutOfRangeException e){
                    failAsExpected=true;
                }
                if(!failAsExpected)
                    throw new RuntimeException("test failed");
            }
        }
        for(int monat = -1; monat >= -24; monat--) {
            for(int tag = -1; tag >= -60; tag--) {
                try {
                    testConstructorErrors(tag,monat,jahr);
                }catch(DateOutOfRangeException e){
                    failAsExpected=true;
                }
                if(!failAsExpected)
                    throw new RuntimeException("test failed");
            }
        }
    }
}

public void testConstructorErrors(int tag, int monat, int jahr) {
    //put additional code here to increase readability of the test loop
    new Datum(tag,monat,jahr);
}
}