You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何编写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);
    }
}

关键细节说明

  1. 嵌套Map定位:通过get("Shelf1")拿到子Map后,用containsEntry定位到具体Book对象,再用assertThatArg对Book做精细化断言。
  2. Payment金额验证:
    • 单个Payment匹配:用extracting(Payment::getAmount).containsExactly(...)精准匹配金额值。
    • 多Payment总和匹配:用hasSum(...)(AssertJ 3.18及以上版本支持)直接验证总金额。
  3. 空指针防护:如果不确定货架是否存在,可先断言shelfBooks.containsKey("Shelf1"),再获取子Map,避免空指针异常。

内容的提问来源于stack exchange,提问作者E Like

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.12 11:50:46