优雅地断言:使用AssertJ进行自定义软断言,以编写更整洁的代码

2024-12-13   出处: eliasnogueira.com  作/译者:Elias/Ares

引言

如果你还不了解什么是软断言(Soft Assert),请阅读《软断言——为何你应在单元测试和集成测试中使用它们?》。

本文是《优雅断言:使用AssertJ创建自定义断言以实现更整洁的代码》的续篇,该文章向你展示了如何使用AssertJ创建自定义断言。在这里,你将学习如何在其方法的基础上进行扩展,从而在自定义断言之上使用软断言方法。

使用AssertJ创建自定义软断言

你可以使用AssertJ库中的Assertions类来实现硬断言,或者创建自定义断言。为了充分利用软断言的优势,我们需要:

  1. 实现一个自定义断言
  2. 创建自定义软断言类,并继承AssertJ中的AbstractSoftAssertions类
自定义断言

在《优雅断言:使用AssertJ创建自定义断言以实现更整洁的代码》一文中,你已经学习了如何创建自定义断言。它看起来像这样:

<pre>public class SimulationAssert extends AbstractAssert<SimulationAssert, Simulation> {
    protected SimulationAssert(Simulation actual) {
        super(actual, SimulationAssert.class);
    }
    public static SimulationAssert assertThat(Simulation actual) {
        return new SimulationAssert(actual);
    }
    public SimulationAssert hasValidInstallments() {
        isNotNull();
        if (actual.getInstallments() < 2 || actual.getInstallments() >= 48) {
            failWithMessage("Installments must be must be equal or greater than 2 and equal or less than 48");
        }
        return this;
    }
    public SimulationAssert hasValidAmount() {
        isNotNull();
        var minimum = new BigDecimal("1.000");
        var maximum = new BigDecimal("40.000");
        if (actual.getAmount().compareTo(minimum) < 0 || actual.getAmount().compareTo(maximum) > 0) {
            failWithMessage("Amount must be equal or greater than $ 1.000 or equal or less than than $ 40.000");
        }
        return this;
    }
}</pre>

自定义断言的使用不仅使测试更具可读性,而且还将测试有效值的责任委托给了它:

<pre>class SimulationsCustomAssertionTest {
    @Test
    void simulationErrorAssertion() {
        var simulation = Simulation.builder().name("John").cpf("9582728395").email("john@gmail.com")
                .amount(new BigDecimal("1.500")).installments(5).insurance(false).build();
        SimulationAssert.assertThat(simulation).hasValidInstallments();
        SimulationAssert.assertThat(simulation).hasValidAmount();
    }
}</pre>

有了自定义断言在手,现在是时候实现自定义软断言了。

创建自定义软断言

创建自定义软断言有一个简单的过程,其前提是已经实现了自定义断言。根据上一篇文章,我们已经有了SimulationAssert类作为自定义断言,现在将创建SimulationSoftAssert作为自定义软断言。以下是具体步骤:

  1. 继承AbstractSoftAssertions类
  2. 创建assertThat()方法,包括:

    • 方法返回对象作为自定义断言类
    • 一个指向断言主体的参数
    • 方法返回方法代理,其参数为自定义断言类和断言主体
    • 创建assertSoftly()方法,包括:

    • 一个指向自定义软断言类的Consumer参数

    • 使用SoftAssertionsProvider.assertSoftly()方法,其中参数为自定义软断言类和方法参数

这些步骤看起来复杂,但实际上,你最终会得到如下内容:

<pre>public class SimulationSoftAssert extends AbstractSoftAssertions {
    public SimulationAssert assertThat(Simulation actual) {
        return proxy(SimulationAssert.class, Simulation.class, actual);
    }
    public static void assertSoftly(Consumer<SimulationSoftAssert> softly) {
        SoftAssertionsProvider.assertSoftly(SimulationSoftAssert.class, softly);
    }
}</pre>
使用自定义软断言

AssertJ的SoftAssertion类负责软断言。以下是一个适用于模拟(Simulation)场景的示例:

<pre>@Test
public void normalSoftAssertion() {
    SoftAssertions.assertSoftly(softly -> {
        var simulation = Simulation.builder().name("John").cpf("9582728395").email("john@gmail.com")
                .amount(new BigDecimal("500")).installments(1).insurance(false).build();
        softly.assertThat(simulation.getInstallments()).isEqualTo(1);
        softly.assertThat(simulation.getAmount()).isEqualTo(500);
    });
}</pre>

使用它(指直接使用SoftAssertions类)的“问题”在于,我们将无法使用已经创建的自定义断言。在上面的示例中,你可以看到安装分期和金额的断言使用了isEqualTo(),这是因为SoftAssertions类无法访问自定义断言。

我们通过创建自定义软断言类解决了这个问题。因此,我们将不再使用SoftAssertions类,而是使用自定义的SimulationSoftAssert类。

<pre>@Test
void simulationValidationErrorSoftAssertion() {
    var simulation = Simulation.builder().name("John").cpf("9582728395").email("john@gmail.com")
            .amount(new BigDecimal("500")).installments(1).insurance(false).build();
    SimulationSoftAssert.assertSoftly(softly -> {
        softly.assertThat(simulation).hasValidInstallments();
        softly.assertThat(simulation).hasValidAmount();
    });
}</pre>

SimulationSoftAssert.assertSoftly()​ 是软断言的提供者,它会调用所有内部方法来管理断言过程中的错误和其他活动。在 assertSoftly()​ 内部使用的 assertThat()​ 是自定义的,它能够通过软断言和断言对象之间的 proxy()​ 访问自定义断言。

使用这种方法,我们通过实现自定义软断言类,在软断言中提供了自定义断言。

结束

就这些啦,各位!

在credit-api项目中,你可以找到一个完全实现且可运行的示例,在那里你可以看到以下内容:

  • SimulationAssert 类
  • 以及SimulationCustomAssertionTest 类中的测试用法

声明:本文为本站编辑转载,文章版权归原作者所有。文章内容为作者个人观点,本站只提供转载参考(依行业惯例严格标明出处和作译者),目的在于传递更多专业信息,普惠测试相关从业者,开源分享,推动行业交流和进步。 如涉及作品内容、版权和其它问题,请原作者及时与本站联系(QQ:1017718740),我们将第一时间进行处理。本站拥有对此声明的最终解释权!欢迎大家通过新浪微博(@测试窝)或微信公众号(测试窝)关注我们,与我们的编辑和其他窝友交流。
24° /241 人阅读/0 条评论 发表评论

登录 后发表评论
最新文章