问小白 wenxiaobai
资讯
历史
科技
环境与自然
成长
游戏
财经
文学与艺术
美食
健康
家居
文化
情感
汽车
三农
军事
旅行
运动
教育
生活
星座命理

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

创作时间:
作者:
@小白创作中心

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

引用
1
来源
1.
https://www.testwo.com/article/2095

引言

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

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

使用AssertJ创建自定义软断言

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

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

自定义断言

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

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;
    }
}

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

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();
    }
}

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

创建自定义软断言

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

  1. 继承AbstractSoftAssertions类
  2. 创建assertThat()方法,包括:
  • 方法返回对象作为自定义断言类
  • 一个指向断言主体的参数
  • 方法返回方法代理,其参数为自定义断言类和断言主体
  1. 创建assertSoftly()方法,包括:
  • 一个指向自定义软断言类的Consumer参数
  • 使用SoftAssertionsProvider.assertSoftly()方法,其中参数为自定义软断言类和方法参数

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

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);
    }
}

使用自定义软断言

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

@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);
    });
}

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

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

@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();
    });
}

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

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

结束

就这些啦,各位!

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

  • SimulationAssert 类
  • 以及SimulationCustomAssertionTest 类中的测试用法
© 2023 北京元石科技有限公司 ◎ 京公网安备 11010802042949号