简体   繁体   English

Junit循环处理预期的异常

[英]Junit handling expected exceptions in a loop

I've learnt how to catch an exception in Junit testing. 我已经学会了如何在Junit测试中捕获异常。 but now I want to loop through arguments which can cause the exception {null, Object.class} currently the test runs for the first loop then exists with a pass and does not check the next loop argument. 但是现在我想遍历可能导致异常{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");

    }
}

So I tried this, it completes the for loop but all the expected exceptions fail as i think Try Catch now steals the exception. 所以我尝试了这一点,它完成了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;
        }
    }
}

Suggestions please? 有什么建议吗?

Is this correct? 这个对吗?

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

I would go with something like that: 我会喜欢这样的东西:

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} });
    }
}

(or two test methods, one for null and one for Object ) (或两种测试方法,一种表示null ,一种表示Object


EDIT: some complements (see comments) 编辑:一些补充(请参阅注释)

The methods annotated with @Parameters returns an Iterable containing Object[] . @Parameters注释的方法返回一个包含Object[]Iterable Each of those Object[] is bound to a @Parameter annotated field (using the value of @Parameter as index [default: 0]). 这些Object[]每一个都绑定到一个@Parameter注释字段(使用@Parameter的值作为索引[默认:0])。 JUnit Parameterized runner will iterate over the @Parameters data and for each array, set fields values and then run every tests in the class. JUnit Parameterized将遍历@Parameters数据,并为每个数组设置字段值,然后运行该类中的每个测试。

See also: Parameterized javadoc 另请参见: Parameterized javadoc

Catching and checking the exception manually within the loop, instead of using expect , may be the way to go there. 可以在循环中手动捕获和检查异常,而不是使用expect Your "is this correct" code block should work if placed within the loop. 如果放置在循环中,则“此正确”代码块应该可以工作。

As this is the first google result when searching I want to add my solution. 因为这是搜索时我要添加解决方案的第一个Google结果。

In my example Datum throws an exception if the date gets invalid arguments in the constructor. 在我的示例中,如果日期在构造函数中获取了无效的参数,则Datum会引发异常。

To test this I wanted to test that the constructor will not accept invalid input and throw an exception. 为了测试这一点,我想测试构造函数将不会接受无效输入并抛出异常。

I test a range of example-cases that should be rejected with a for loop. 我测试了应该用for循环拒绝的一系列示例案例。

To test that the loop threw an exception in every iteration I simply added a boolean variable that was set true in a catch for this exact exception on every iteration, if the variable was false at the end of the iteration then a runtime exception would be thrown that will let the test fail. 为了测试循环是否在每次迭代中都引发异常,我仅添加了一个布尔变量,该变量在每次迭代中均针对此确切异常在catch中设置为true,如果该变量在迭代结束时为false,则将引发运行时异常。那会让测试失败。

I think this is far easier to read for teammembers afterwards without any extravagant knowledge for junit tests. 我认为这对于以后的团队成员来说很容易阅读,而无需任何关于junit测试的丰富知识。 It is much easier to use for beginners as well. 对于初学者来说,它也更容易使用。

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);
}
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM