如何编写JUnit测试用例验证嵌套Map中的Book及Payment对象?
解决JUnit测试
Map<String, Map<Long, Book>>结构及Payment验证问题 先解决extracting方法未定义的问题
这个报错通常是因为你没引入AssertJ依赖,或者没导入它的静态断言方法。AssertJ对复杂嵌套结构的断言支持远优于原生JUnit,是处理这类场景的首选工具。
引入依赖(Maven示例)
<dependency> <groupId>org.assertj</groupId> <artifactId>assertj-core</artifactId> <version>3.24.2</version> <!-- 替换为最新稳定版即可 --> <scope>test</scope> </dependency>
导入静态断言方法
在测试类顶部添加:
import static org.assertj.core.api.Assertions.*;
完整测试用例示例
假设你要测试的目标Map是Map<String, Map<Long, Book>> shelfBooks,以下是完全符合你验证要求的测试代码:
import org.junit.jupiter.api.Test; import java.util.List; import static org.assertj.core.api.Assertions.*; class BookMapValidationTest { @Test void testShelfBooksStructureAndContent() { // 替换为你实际获取待测试Map的业务方法调用 Map<String, Map<Long, Book>> shelfBooks = getTargetShelfBooks(); // 验证顶层Map包含指定货架键 assertThat(shelfBooks).containsKeys("Shelf1", "Shelf2"); // 验证Shelf1下的Book1 assertThat(shelfBooks.get("Shelf1")) .containsEntry(1L, assertThatArg(book -> { assertThat(book.getId()).isEqualTo(1L); assertThat(book.getName()).isEqualTo("my book"); // 验证payments的金额:如果是单个Payment金额为10 assertThat(book.getPayments()) .extracting(Payment::getAmount) .containsExactly(10.0); // 根据实际字段类型用int/double // 如果是多个Payment总金额为10,替换为下面的断言 // assertThat(book.getPayments()) // .extracting(Payment::getAmount) // .asList() // .hasSum(10.0); })); // 验证Shelf2下的Book2 assertThat(shelfBooks.get("Shelf2")) .containsEntry(5L, assertThatArg(book -> { assertThat(book.getId()).isEqualTo(5L); assertThat(book.getName()).isEqualTo("my book2"); assertThat(book.getPayments()) .extracting(Payment::getAmount) .containsExactly(50.0); })); } // 模拟待测试的Map生成,实际场景中删除此方法,替换为业务逻辑调用 private Map<String, Map<Long, Book>> getTargetShelfBooks() { Payment payment1 = new Payment(1L, "PAY001", 10.0, "Alice"); Book book1 = new Book(1L, "my book", "test desc 1", List.of(payment1)); Payment payment2 = new Payment(2L, "PAY002", 50.0, "Bob"); Book book2 = new Book(5L, "my book2", "test desc 2", List.of(payment2)); Map<Long, Book> shelf1Books = Map.of(1L, book1); Map<Long, Book> shelf2Books = Map.of(5L, book2); return Map.of("Shelf1", shelf1Books, "Shelf2", shelf2Books); } }
关键细节说明
- 嵌套Map定位:通过
get("Shelf1")拿到子Map后,用containsEntry定位到具体Book对象,再用assertThatArg对Book做精细化断言。 - Payment金额验证:
- 单个Payment匹配:用
extracting(Payment::getAmount).containsExactly(...)精准匹配金额值。 - 多Payment总和匹配:用
hasSum(...)(AssertJ 3.18及以上版本支持)直接验证总金额。
- 单个Payment匹配:用
- 空指针防护:如果不确定货架是否存在,可先断言
shelfBooks.containsKey("Shelf1"),再获取子Map,避免空指针异常。
内容的提问来源于stack exchange,提问作者E Like
相关产品推荐
相关产品推荐

