junit5测试异常处理_在JUnit中处理异常的3种⽅式。选择哪⼀
个?
junit 5测试异常处理
在JUnit中,有3种流⾏的⽅式来处理测试代码中的异常:
试捕习语
使⽤JUnit规则
带注解
我们应该使⽤哪⼀个?何时使⽤?
试捕习语
这个习语是最受欢迎的习语之⼀,因为它已在JUnit 3中使⽤。
@Test
public void throwsExceptionWhenNegativeNumbersAreGiven() {
try {fantastic
calculator.add("-1,-2,3");
thickfail("Should throw an exception if one or more of given numbers are negative");
} catch (Exception e) {
asrtThat(e)
.isInstanceOf(IllegalArgumentException.class)
.hasMessage("negatives not allowed: [-1, -2]");
}
}同性恋 英文
上⾯的⽅法是⼀种常见的模式。 当没有引发异常并且在catch⼦句中验证了异常本⾝时,测试将失败(在上⾯的⽰例中,我使⽤了FEST Fluent断⾔),尽管它很好,但我更喜欢使⽤
ExpectedException规则。
使⽤JUnit规则
可以使⽤创建相同的⽰例
ExceptedException规则。 规则必须是标有@Rule批注的公共字段。 请注意,“抛出”规则可能会在许多测试中重复使⽤。
@Rule
public ExpectedException thrown = ();
曙色
@Test
dress的复数形式public void throwsExceptionWhenNegativeNumbersAreGiven() {
// arrange
// act
calculator.add("-1,-2,3");
}
总的来说,我发现上⾯的代码更具可读性,因此我在项⽬中使⽤了这种⽅法。
当未引发异常时,您将收到以下消息: java.lang.AsrtionError:预期引发的测试(java.lang.IllegalArgumentException的实例和带有消息“不允许负数的异常:[-1,-2]” ) 。 挺棒的。
但并⾮所有例外情况我都可以通过上述⽅法进⾏检查。 有时我只需要检查抛出的异常的类型,然后使⽤@Test批注。
带注解
@Test (expected = IllegalArgumentException.class)
public void throwsExceptionWhenNegativeNumbersAreGiven() {
swim的过去式
// act
calculator.add("-1,-2,3");
}
当未引发异常时,您将收到以下消息: java.lang.AsrtionError:预期的异常:java.lang.IllegalArgumentException
使⽤这种⽅法时,您需要⼩⼼。 有时很容易想到⼀般的Exception , RuntimeException甚⾄Throwable 。 这被认为是⼀种不好的做法,因为您的代码可能会在实际未预期的地⽅引发异常,并且测试仍将通过!
综上所述,在我的代码中,我使⽤两种⽅法: JUnit规则和注释 。 优点是:
代码不引发异常时的错误消息会⾃动处理
可读性得到改善
创建的代码更少
您的喜好是什么?
我听说过处理异常的第四种⽅式(我的⼀位同事在阅读本⽂后提出了建议)–使⽤⾃定义注释。
乍⼀看,实际上该解决⽅案看起来不错,但是它需要您⾃⼰的JUnit运⾏器,因此它有缺点:您不能将此批注与Mockito运⾏器⼀起使⽤。
作为编码实践,我创建了这样的注释,所以也许有⼈觉得它有⽤
⽤法
@RunWith(ExpectsExceptionRunner.class)
public class StringCalculatorTest {
@Test
@ExpectsException(type = IllegalArgumentException.class, message = "negatives not allowed: [-1]")
public void throwsExceptionWhenNegativeNumbersAreGiven() throws Exception {戒具
// act
calculator.add("-1,-2,3");
}
}
上⾯的测试将失败,并显⽰⼀条消息: java.lang.Exception:意外的异常消息,预期的
但是是
注释
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD})
public @interface ExpectsException {
Class type();
String message() default "";
}
跑步者
带有复制和粘贴代码的跑步者
public class ExpectsExceptionRunner extends BlockJUnit4ClassRunner {
public ExpectsExceptionRunner(Class klass) throws InitializationError {
super(klass);
}
@Override
protected Statement possiblyExpectingExceptions(FrameworkMethod method, Object test, Statement next) { ExpectsException annotation = Annotation(ExpectsException.class);
if (annotation == null) {
return next;
}
return new ExpectExceptionWithMessage(next, pe(), ssage());
}
class ExpectExceptionWithMessage extends Statement {
private final Statement next;
private final Class expected;
private final String expectedMessage;
public ExpectExceptionWithMessage(Statement next, Class expected, String expectedMessage) {
< = next;
}
@Override
public void evaluate() throws Exception {
boolean complete = fal;
try {
next.evaluate();
complete = true;
} catch (AssumptionViolatedException e) {
throw e;
} catch (Throwable e) {
trade key
if (!expected.Class())) {
String message = "Unexpected exception, expected<"
+ Name() + "> but was <"
+ e.getClass().getName() + ">";
throw new Exception(message, e);
}
if (isNotNull(expectedMessage) && !expectedMessage.Message())) {
String message = "Unexpected exception message, expected<"
dowcorning
+ expectedMessage + "> but was<"
+ e.getMessage() + ">";
throw new Exception(message, e);
}
}
if (complete) {
throw new AsrtionError("Expected exception: "
+ Name());
}
}
private boolean isNotNull(String s) {
return s != null && !s.isEmpty();
}
}
suited
}
参考: 从我们的 Rafal Borowiec在博客上获得。
junit 5测试异常处理