java junit 异常_JUnit:使用Java 8和Lambda表达式测试异常
java junit 異常
在JUnit中,有許多方法可以在測(cè)試代碼中測(cè)試異常,包括try-catch idiom JUnit @Rule和catch-exception庫(kù)。 從Java 8開(kāi)始,我們還有另一種處理異常的方法:使用lambda表達(dá)式。 在這篇簡(jiǎn)短的博客文章中,我將演示一個(gè)簡(jiǎn)單的示例,說(shuō)明如何利用Java 8和lambda表達(dá)式的功能來(lái)測(cè)試JUnit中的異常。
注意:撰寫此博客文章的動(dòng)機(jī)是在catch-exception項(xiàng)目頁(yè)面上發(fā)布的消息:
Java 8的lambda表達(dá)式將使catch-exception冗余。 因此,該項(xiàng)目將不再維護(hù)
SUT –被測(cè)系統(tǒng)
我們將測(cè)試以下2類拋出的異常。
第一個(gè):
class DummyService {public void someMethod() {throw new RuntimeException("Runtime exception occurred");}public void someOtherMethod() {throw new RuntimeException("Runtime exception occurred",new IllegalStateException("Illegal state"));} }第二個(gè):
class DummyService2 {public DummyService2() throws Exception {throw new Exception("Constructor exception occurred");}public DummyService2(boolean dummyParam) throws Exception {throw new Exception("Constructor exception occurred");} }所需語(yǔ)法
我的目標(biāo)是實(shí)現(xiàn)與catch-exception庫(kù)接近的語(yǔ)法:
package com.github.kolorobot.exceptions.java8;import org.junit.Test; import static com.github.kolorobot.exceptions.java8.ThrowableAssertion.assertThrown;public class Java8ExceptionsTest {@Testpublic void verifiesTypeAndMessage() {assertThrown(new DummyService()::someMethod) // method reference// assertions.isInstanceOf(RuntimeException.class).hasMessage("Runtime exception occurred").hasNoCause();}@Testpublic void verifiesCauseType() {assertThrown(() -> new DummyService().someOtherMethod(true)) // lambda expression// assertions.isInstanceOf(RuntimeException.class).hasMessage("Runtime exception occurred").hasCauseInstanceOf(IllegalStateException.class);}@Testpublic void verifiesCheckedExceptionThrownByDefaultConstructor() {assertThrown(DummyService2::new) // constructor reference// assertions.isInstanceOf(Exception.class).hasMessage("Constructor exception occurred");}@Testpublic void verifiesCheckedExceptionThrownConstructor() {assertThrown(() -> new DummyService2(true)) // lambda expression// assertions.isInstanceOf(Exception.class).hasMessage("Constructor exception occurred");}@Test(expected = ExceptionNotThrownAssertionError.class) // making test passpublic void failsWhenNoExceptionIsThrown() {// expected exception not thrownassertThrown(() -> System.out.println());} }注意:與catch-exception相比的優(yōu)勢(shì)在于,我們將能夠測(cè)試引發(fā)異常的構(gòu)造函數(shù)。
創(chuàng)建“圖書館”
合成糖
assertThrown是一個(gè)靜態(tài)工廠方法,它創(chuàng)建一個(gè)ThrowableAssertion的新實(shí)例,并引用了捕獲的異常。
package com.github.kolorobot.exceptions.java8;public class ThrowableAssertion {public static ThrowableAssertion assertThrown(ExceptionThrower exceptionThrower) {try {exceptionThrower.throwException();} catch (Throwable caught) {return new ThrowableAssertion(caught);}throw new ExceptionNotThrownAssertionError();}// other methods omitted for now }ExceptionThrower是@FunctionalInterface ,可以使用lambda表達(dá)式,方法引用或構(gòu)造函數(shù)引用創(chuàng)建實(shí)例。 assertThrown接受ExceptionThrower將期望并準(zhǔn)備處理異常。
@FunctionalInterface public interface ExceptionThrower {void throwException() throws Throwable; }斷言
最后,我們需要?jiǎng)?chuàng)建一些斷言,以便可以在測(cè)試代碼中驗(yàn)證有關(guān)teste異常的解釋。 實(shí)際上, ThrowableAssertion是一種自定義斷言,為我們提供了一種有效地驗(yàn)證所捕獲異常的方法。 在下面的代碼中,我使用了Hamcrest匹配器來(lái)創(chuàng)建斷言。 ThrowableAssertion類的完整來(lái)源:
package com.github.kolorobot.exceptions.java8;import org.hamcrest.Matchers; import org.junit.Assert;public class ThrowableAssertion {public static ThrowableAssertion assertThrown(ExceptionThrower exceptionThrower) {try {exceptionThrower.throwException();} catch (Throwable caught) {return new ThrowableAssertion(caught);}throw new ExceptionNotThrownAssertionError();}private final Throwable caught;public ThrowableAssertion(Throwable caught) {this.caught = caught;}public ThrowableAssertion isInstanceOf(Class<? extends Throwable> exceptionClass) {Assert.assertThat(caught, Matchers.isA((Class<Throwable>) exceptionClass));return this;}public ThrowableAssertion hasMessage(String expectedMessage) {Assert.assertThat(caught.getMessage(), Matchers.equalTo(expectedMessage));return this;}public ThrowableAssertion hasNoCause() {Assert.assertThat(caught.getCause(), Matchers.nullValue());return this;}public ThrowableAssertion hasCauseInstanceOf(Class<? extends Throwable> exceptionClass) {Assert.assertThat(caught.getCause(), Matchers.notNullValue());Assert.assertThat(caught.getCause(), Matchers.isA((Class<Throwable>) exceptionClass));return this;} }AssertJ實(shí)施
如果您使用AssertJ庫(kù),則可以利用org.assertj.core.api.ThrowableAssert輕松創(chuàng)建ThrowableAssertion AssertJ版本,它提供了許多org.assertj.core.api.ThrowableAssert斷言。 該類的實(shí)現(xiàn)比上面介紹的Hamcrest更簡(jiǎn)單。
package com.github.kolorobot.exceptions.java8;import org.assertj.core.api.Assertions; import org.assertj.core.api.ThrowableAssert;public class AssertJThrowableAssert {public static ThrowableAssert assertThrown(ExceptionThrower exceptionThrower) {try {exceptionThrower.throwException();} catch (Throwable throwable) {return Assertions.assertThat(throwable);}throw new ExceptionNotThrownAssertionError();} }AssertJ的示例測(cè)試:
public class AssertJJava8ExceptionsTest {@Testpublic void verifiesTypeAndMessage() {assertThrown(new DummyService()::someMethod).isInstanceOf(RuntimeException.class).hasMessage("Runtime exception occurred").hasMessageStartingWith("Runtime").hasMessageEndingWith("occurred").hasMessageContaining("exception").hasNoCause();} }摘要
僅用幾行代碼,我們構(gòu)建了非常酷的代碼,可幫助我們?cè)贘Unit中測(cè)試異常而無(wú)需任何其他庫(kù)。 這僅僅是一個(gè)開(kāi)始。 利用Java 8和lambda表達(dá)式的強(qiáng)大功能!
資源資源
- GitHub上提供了本文的源代碼 (請(qǐng)看com.github.kolorobot.exceptions.java8包)
- 我的其他一些文章關(guān)于在JUnit中測(cè)試異常。 請(qǐng)看一看:
- 定制斷言
翻譯自: https://www.javacodegeeks.com/2014/07/junit-testing-exception-with-java-8-and-lambda-expressions.html
java junit 異常
總結(jié)
以上是生活随笔為你收集整理的java junit 异常_JUnit:使用Java 8和Lambda表达式测试异常的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 老安卓游戏网站(老安卓游戏)
- 下一篇: 编制与备案制(备案制进编)