处理JUnit中异常的另一种方法:catch-exception

本文介绍了catch-exception库,一个用于简洁、快速地捕获和分析异常的工具。通过Maven添加依赖后,可以使用一行代码实现异常捕获。文中展示了基本用法和与Hamcrest结合验证自定义异常的例子,强调了其在测试中的便利性和可读性。
摘要由CSDN通过智能技术生成

JUnit中有许多处理异常的方法 (JUnit中有3种处理异常的方法。选择哪一种呢? JUnit ExpectedException规则:超越了基础 )。 在本文中,我将介绍建议尝试的catch-exception库。 简而言之, catch-exceptions是一个库,可在一行代码中捕获异常,并使它们可用于进一步分析。

通过Maven安装

为了快速入门,我使用了带有一组测试依赖项( JUnit,Mocito,Hamcrest,AssertJ )的单元测试演示项目,并添加了catch-exceptions

<dependency>
    <groupId>com.googlecode.catch-exception</groupId>
    <artifactId>catch-exception</artifactId>
    <version>1.2.0</version>
    <scope>test</scope>
</dependency>

因此,依赖关系树如下所示:

[INFO] --- maven-dependency-plugin:2.1:tree @ unit-testing-demo ---
[INFO] com.github.kolorobot:unit-testing-demo:jar:1.0.0-SNAPSHOT
[INFO] +- org.slf4j:slf4j-api:jar:1.5.10:compile
[INFO] +- org.slf4j:jcl-over-slf4j:jar:1.5.10:runtime
[INFO] +- org.slf4j:slf4j-log4j12:jar:1.5.10:runtime
[INFO] +- log4j:log4j:jar:1.2.15:runtime
[INFO] +- junit:junit:jar:4.11:test
[INFO] +- org.mockito:mockito-core:jar:1.9.5:test
[INFO] +- org.assertj:assertj-core:jar:1.5.0:test
[INFO] +- org.hamcrest:hamcrest-core:jar:1.3:test
[INFO] +- org.hamcrest:hamcrest-library:jar:1.3:test
[INFO] +- org.objenesis:objenesis:jar:1.3:test
[INFO] \- com.googlecode.catch-exception:catch-exception:jar:1.2.0:test

入门

被测系统(SUT):

class ExceptionThrower {
 
    void someMethod() {
        throw new RuntimeException("Runtime exception occurred");
    }
 
    void someOtherMethod() {
        throw new RuntimeException("Runtime exception occurred",
                new IllegalStateException("Illegal state"));
    }
 
    void yetAnotherMethod(int code) {
        throw new CustomException(code);
    }
}

带有AssertJ断言的基本catch-exception BDD样式方法示例:

import org.junit.Test;
 
import static com.googlecode.catchexception.CatchException.*;
import static com.googlecode.catchexception.apis.CatchExceptionAssertJ.*;
 
public class CatchExceptionsTest {
 
    @Test
    public void verifiesTypeAndMessage() {
        when(new SomeClass()).someMethod();
 
        then(caughtException())
                .isInstanceOf(RuntimeException.class)
                .hasMessage("Runtime exception occurred")
                .hasMessageStartingWith("Runtime")
                .hasMessageEndingWith("occured")
                .hasMessageContaining("exception")
                .hasNoCause();               
    }
}

看起来不错。 简洁,可读。 没有JUnit运行者。 请注意,我指定了我希望引发异常的SomeClass方法。 可以想象,我可以在一个测试中检查多个异常。 尽管我不推荐这种方法,因为这可能违反了测试的单一责任。

顺便说一句,如果您正在使用Eclipse,这可能对您来说很方便: 在Eclipse中创建JUnit测试时,改进具有静态成员类型的内容辅助

查明原因

我认为以下代码无需评论:

import org.junit.Test;
 
import static com.googlecode.catchexception.CatchException.*;
import static com.googlecode.catchexception.apis.CatchExceptionAssertJ.*;
 
public class CatchExceptionsTest {
 
    @Test
    public void verifiesCauseType() {
        when(new ExceptionThrower()).someOtherMethod();
        then(caughtException())
                .isInstanceOf(RuntimeException.class)
                .hasMessage("Runtime exception occurred")
                .hasCauseExactlyInstanceOf(IllegalStateException.class)
                .hasRootCauseExactlyInstanceOf(IllegalStateException.class);
    }
}

验证Hamcrest的自定义例外

为了验证我用我以前的Hamcrest匹配代码自定义异常

class CustomException extends RuntimeException {
    private final int code;
 
    public CustomException(int code) {
        this.code = code;
    }
 
    public int getCode() {
        return code;
    }
}
 
class ExceptionCodeMatches extends TypeSafeMatcher<CustomException> {
 
    private int expectedCode;
 
    public ExceptionCodeMatches(int expectedCode) {
        this.expectedCode = expectedCode;
    }
 
    @Override
    protected boolean matchesSafely(CustomException item) {
        return item.getCode() == expectedCode;
    }
 
    @Override
    public void describeTo(Description description) {
        description.appendText("expects code ")
                .appendValue(expectedCode);
    }
 
    @Override
    protected void describeMismatchSafely(CustomException item, Description mismatchDescription) {
        mismatchDescription.appendText("was ")
                .appendValue(item.getCode());
    }
}

和测试:

import org.junit.Test;
 
import static com.googlecode.catchexception.CatchException.*;
import static org.junit.Assert.*;
 
public class CatchExceptionsTest {
 
    @Test
    public void verifiesCustomException() {
        catchException(new ExceptionThrower(), CustomException.class).yetAnotherMethod(500);
        assertThat((CustomException) caughtException(), new ExceptionCodeMatcher(500));
    }
}

摘要

捕获异常看起来真的很好。 快速入门很容易。 我看到了一些优于JUnit方法规则的优点。 如果有机会,我将更彻底地调查图书馆,希望在一个实际项目中进行。

如果您有兴趣,请查看我的其他帖子:

翻译自: https://www.javacodegeeks.com/2014/04/yet-another-way-to-handle-exceptions-in-junit-catch-exception.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值