Mockito单元测试DynamoDB Repository返回null问题排查求助
问题原因及修复方案
核心问题:Key对象匹配失败
测试返回null的根本原因是Mockito的方法调用匹配不生效:
- 测试类中你mock了
Key key实例,但实际getBook方法里是通过Key.builder().partitionValue(bookId).build()创建了全新的Key对象,和mock的key并非同一个实例。 - Mockito默认按对象实例进行匹配,因此
when(dyamoDbTable.getItem(key))这个存根逻辑不会被触发,getItem方法返回默认值null。
额外优化点:TableSchema存根可更简洁
当前TableSchema的mock能正常工作,但重复调用TableSchema.fromBean(Book.class)不够清晰,建议提前缓存schema实例。
具体修复步骤
1. 移除无用的Key mock
测试类中@Mock private Key key;完全未被使用,直接删除即可。
2. 修改getItem的存根逻辑,使用参数匹配器
将原代码:
when(dyamoDbTable.getItem(key)).thenReturn(book);
替换为以下两种方式之一:
方式一:匹配任意Key实例(简单直接)
import static org.mockito.ArgumentMatchers.any; // ... when(dyamoDbTable.getItem(any(Key.class))).thenReturn(book);
方式二:精确匹配Key的partitionValue(更严谨)
import static org.mockito.ArgumentMatchers.argThat; // ... when(dyamoDbTable.getItem(argThat(k -> BOOK_ID.equals(k.partitionValue().value())))).thenReturn(book);
3. 优化TableSchema的存根(可选但推荐)
将静态方法mock和client table的存根逻辑调整为:
@Test void testGetBook() { Book book = HelperMethod.createBook(); // 提前创建schema实例 BeanTableSchema<Book> bookSchema = BeanTableSchema.create(Book.class); tableSchema.when(() -> TableSchema.fromBean(Book.class)) .thenReturn(bookSchema); // 直接用提前创建的schema实例匹配 when(dynamoDbEnhancedClient.table("Book", bookSchema)).thenReturn(dyamoDbTable); // 应用上面的参数匹配器存根getItem when(dyamoDbTable.getItem(any(Key.class))).thenReturn(book); final var result = repository.getBook(BOOK_ID); assertEquals(book, result); }
修复后逻辑说明
修改后,Mockito会匹配getBook方法中创建的任意Key实例(或符合partitionValue条件的Key),触发存根逻辑返回预设的Book对象,断言即可正常通过。
内容的提问来源于stack exchange,提问作者user15125148
相关产品推荐
相关产品推荐

