[英]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.