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

我想通过一次断言调用来断言一个对象的多个属性。


使用 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))

但这不是重点。


慕妹3146593
浏览 142回答 3
3回答

慕斯709654

使用 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));

烙印99

使用 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()要避免的重写。

守着星空守着你

你可以使用Assertions.assertAll:assertAll("product",   () -> assertEquals("Coat", product.getName()),   () -> assertTrue(product.isAvaikable()));assertAll 可以接受任意多的单独断言。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Java