为了账号安全,请及时绑定邮箱和手机立即绑定

JUnit5:如何通过单个断言调用断言一个对象的多个属性?

JUnit5:如何通过单个断言调用断言一个对象的多个属性?

慕妹3146593 2023-06-04 17:41:05
我想通过一次断言调用来断言一个对象的多个属性。使用 JUnit 4 和 Hamcrest 我会写这样的东西:assertThat(product, allOf(        hasProperty("name", is("Coat")),        hasProperty("available", is(true)),        hasProperty("amount", is(12)),        hasProperty("price", is(new BigDecimal("88.0")))));问:如何使用 JUnit 5 和 AssertJ 在单个断言调用中断言多个属性?或者,或者,在 JUnit 5 世界中最好的方法是什么。注意:我当然可以创建一个具有所有需要的属性的对象并执行assertThat(actualProduct, is(expectedProduct))但这不是重点。
查看完整描述

3 回答

?
慕斯709654

TA贡献1840条经验 获得超5个赞

使用 AssertJ,另一种选择是使用returns

import static org.assertj.core.api.Assertions.from;


assertThat(product)

    .returns("Coat", from(Product::getName))

    .returns(true, from(Product::getAvailable))

     //

     // or without 'from()'

     //

    .returns(12, Product::getAmount)

    .returns(new BigDecimal("88.0"), Product::getPrice);

有点冗长,但我发现与extracting/相比更容易阅读contains

请注意,这from只是一个可选的语法糖,以提高可读性。


从 3.22.0 开始,doesNotReturn也可用。这对于事先不知道预期值的非空字段很有用。

assertThat(product)
    .returns("Coat", from(Product::getName))
    .returns(true, from(Product::getAvailable))
    .doesNotReturn(42, from(Product::getAmount))
    .doesNotReturn(null, from(Product::getPrice));


查看完整回答
反对 回复 2023-06-04
?
烙印99

TA贡献1829条经验 获得超13个赞

使用 AssertJ 最接近的是:

assertThat(product).extracting("name", "available", "amount", "price")
                   .containsExactly("Coat", true, 12, new BigDecimal("88.0"));

但我不喜欢用Strings 引用字段名称,因为它们作为字段名称的有效性仅在运行时检查(已知的反射问题),并且这些Strings 也可能在我们从 IDE 执行的重构操作期间被错误地更新。

虽然有点冗长,但我更喜欢:

assertThat(product).extracting(Product::getName, Product::getAvailable, 
                               Product::getAmount, Product::getPrice)
                   .containsExactly("Coat", true, 12, new BigDecimal("88.0"));

您引用的 AssertJ 优于 Hamcrest 的优势在于它非常流畅:因此在大多数情况下,您需要一次导入:import org.assertj.core.api.Assertions;对于集合断言,有时需要:org.assertj.core.groups.Tuple;

这里是 JUnit 5 或 4;这并不重要,因为对于非常简单的情况,您只会将 JUnit 用作测试运行程序,而让 AssertJ 执行断言。

或者,或者,在 JUnit 5 世界中最好的方法是什么。

JUnit 5(作为第 4 个版本)不提供灵活流畅的断言功能。因此,使用 JUnit 5 的最佳方式来做这件事必然会产生更多的样板代码:与要断言的字段一样多的断言或出于公平原因equals()/hashCode()要避免的重写。


查看完整回答
反对 回复 2023-06-04
?
守着星空守着你

TA贡献1799条经验 获得超8个赞

你可以使用Assertions.assertAll:


assertAll("product",

   () -> assertEquals("Coat", product.getName()),

   () -> assertTrue(product.isAvaikable())

);

assertAll 可以接受任意多的单独断言。

查看完整回答
反对 回复 2023-06-04
  • 3 回答
  • 0 关注
  • 104 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信