junit 5测试异常处理_在JUnit中处理异常的3种方式。 选择哪一个?
junit 5測試異常處理
在JUnit中,有3種流行的方式來處理測試代碼中的異常:
- 試捕習(xí)語
- 使用JUnit規(guī)則
- 帶注解
我們應(yīng)該使用哪一個?何時使用?
試捕習(xí)語
這個習(xí)語是最受歡迎的習(xí)語之一,因為它已在JUnit 3中使用。
@Testpublic void throwsExceptionWhenNegativeNumbersAreGiven() {try {calculator.add("-1,-2,3");fail("Should throw an exception if one or more of given numbers are negative");} catch (Exception e) {assertThat(e).isInstanceOf(IllegalArgumentException.class).hasMessage("negatives not allowed: [-1, -2]");}} 上面的方法是一種常見的模式。 當(dāng)沒有引發(fā)異常并且在catch子句中驗證了異常本身時,測試將失敗(在上面的示例中,我使用了FEST Fluent斷言),盡管它很好,但我更喜歡使用
ExpectedException規(guī)則。
使用JUnit規(guī)則
可以使用創(chuàng)建相同的示例
ExceptedException規(guī)則。 規(guī)則必須是標(biāo)有@Rule批注的公共字段。 請注意,“拋出”規(guī)則可能會在許多測試中重復(fù)使用。
總的來說,我發(fā)現(xiàn)上面的代碼更具可讀性,因此我在項目中使用了這種方法。
當(dāng)未引發(fā)異常時,您將收到以下消息: java.lang.AssertionError:預(yù)期引發(fā)的測試(java.lang.IllegalArgumentException的實例和帶有消息“不允許負(fù)數(shù)的異常:[-1,-2]” ) 。 挺棒的。
但并非所有例外情況我都可以通過上述方法進(jìn)行檢查。 有時我只需要檢查拋出的異常的類型,然后使用@Test批注。
帶注解
@Test (expected = IllegalArgumentException.class)public void throwsExceptionWhenNegativeNumbersAreGiven() {// actcalculator.add("-1,-2,3");}當(dāng)未引發(fā)異常時,您將收到以下消息: java.lang.AssertionError:預(yù)期的異常:java.lang.IllegalArgumentException
使用這種方法時,您需要小心。 有時很容易想到一般的Exception , RuntimeException甚至Throwable 。 這被認(rèn)為是一種不好的做法,因為您的代碼可能會在實際未預(yù)期的地方引發(fā)異常,并且測試仍將通過!
綜上所述,在我的代碼中,我使用兩種方法: JUnit規(guī)則和注釋 。 優(yōu)點(diǎn)是:
- 代碼不引發(fā)異常時的錯誤消息會自動處理
- 可讀性得到改善
- 創(chuàng)建的代碼更少
您的喜好是什么?
我聽說過處理異常的第四種方式(我的一位同事在閱讀本文后提出了建議)–使用自定義注釋。
乍一看,實際上該解決方案看起來不錯,但是它需要您自己的JUnit運(yùn)行器,因此它有缺點(diǎn):您不能將此批注與Mockito運(yùn)行器一起使用。
作為編碼實踐,我創(chuàng)建了這樣的注釋,所以也許有人覺得它有用
用法
@RunWith(ExpectsExceptionRunner.class) public class StringCalculatorTest {@Test@ExpectsException(type = IllegalArgumentException.class, message = "negatives not allowed: [-1]")public void throwsExceptionWhenNegativeNumbersAreGiven() throws Exception {// actcalculator.add("-1,-2,3");}}上面的測試將失敗,并顯示一條消息: java.lang.Exception:意外的異常消息,預(yù)期的
但是是
注釋
@Retention(RetentionPolicy.RUNTIME) @Target({ElementType.METHOD}) public @interface ExpectsException {Class type();String message() default ""; }帶有復(fù)制和粘貼代碼的跑步者
public class ExpectsExceptionRunner extends BlockJUnit4ClassRunner {public ExpectsExceptionRunner(Class klass) throws InitializationError {super(klass);}@Overrideprotected Statement possiblyExpectingExceptions(FrameworkMethod method, Object test, Statement next) {ExpectsException annotation = method.getAnnotation(ExpectsException.class);if (annotation == null) {return next;}return new ExpectExceptionWithMessage(next, annotation.type(), annotation.message());}class ExpectExceptionWithMessage extends Statement {private final Statement next;private final Class expected;private final String expectedMessage;public ExpectExceptionWithMessage(Statement next, Class expected, String expectedMessage) {this.next = next;this.expected = expected;this.expectedMessage = expectedMessage;}@Overridepublic void evaluate() throws Exception {boolean complete = false;try {next.evaluate();complete = true;} catch (AssumptionViolatedException e) {throw e;} catch (Throwable e) {if (!expected.isAssignableFrom(e.getClass())) {String message = "Unexpected exception, expected<"+ expected.getName() + "> but was <"+ e.getClass().getName() + ">";throw new Exception(message, e);}if (isNotNull(expectedMessage) && !expectedMessage.equals(e.getMessage())) {String message = "Unexpected exception message, expected<"+ expectedMessage + "> but was<"+ e.getMessage() + ">";throw new Exception(message, e);}}if (complete) {throw new AssertionError("Expected exception: "+ expected.getName());}}private boolean isNotNull(String s) {return s != null && !s.isEmpty();}}} 參考: 在JUnit中處理異常的3種方法。 選擇哪一個? 從我們的JCG合作伙伴 Rafal Borowiec在Codeleak.pl博客上獲得。翻譯自: https://www.javacodegeeks.com/2013/11/3-ways-of-handling-exceptions-in-junit-which-one-to-choose.html
junit 5測試異常處理
總結(jié)
以上是生活随笔為你收集整理的junit 5测试异常处理_在JUnit中处理异常的3种方式。 选择哪一个?的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 苹果手机是什么字体 苹果手机字体是什么
- 下一篇: 怎么做电子版 电子版文件怎么做