模拟增强的 DynamoDbTable CRUD 操作

Mock enhanced DynamoDbTable CRUD operations

如何模拟software.amazon.awssdk.enhanced.dynamodb.DynamoDbTable.getItem?

到目前为止,我已经尝试了以下方法,它从 SDK 内部抛出 NullPointerException。 知道如何模拟 table CRUD 操作吗?

  @Mock private DynamoDbEnhancedClient enhdynamodb;
  @Mock private DynamoDbClient dynamodb;
  @Mock private DynamoDbTable<EventRecord> dyamodbTable;
  @Mock private SecurityContext securityContext;

  @Before
  public void setup() {
    MockitoAnnotations.initMocks(this);
    when(securityContext.getUserPrincipal()).thenReturn(principal);
    enhdynamodb = DynamoDbEnhancedClient.builder().dynamoDbClient(dynamodb).build();
    dyamodbTable = enhdynamodb.table(TABLE_NAME, TableSchema.fromBean(EventRecord.class));
    service = new EventsService(tokenSerializer, enhdynamodb, configProvider, clock);
    service.setSecurityContext(securityContext);
  }


  @Test
  public void getEvent_null_notFound() {
    String userId = UUID.randomUUID().toString();
    String eventId = UUID.randomUUID().toString();
    GetItemResponse response = GetItemResponse.builder().build();
    EventRecord event = null;
    when(principal.getName()).thenReturn(userId);
    when(dyamodbTable.getItem(any(GetItemEnhancedRequest.class))).thenReturn(event);   
    assertThatThrownBy(() -> service.getEvent(eventId)).isInstanceOf(NotFoundApiException.class);
  }


  public Event getEvent(String eventId) {
    log.info("Getting event {}", eventId);
    EventRecord eventRecord = loadEvent(eventId);
    return modelMapper.map(eventRecord, Event.class);
  }

  private EventRecord loadEvent(final String eventId) {    
    String userId = securityContext.getUserPrincipal().getName();
    EventRecord event =
        getTable()
            .getItem(
                GetItemEnhancedRequest.builder()
                    .consistentRead(Boolean.TRUE)
                    .key(k -> k.partitionValue(userId).sortValue(eventId).build())
                    .build());

    if (event == null) {
      throw new NotFoundApiException(
          new NotFoundException()
              .errorCode("EventNotFound")
              .message(String.format("Event %s can not be found.", eventId)));
    }
    return event;
  }

  private DynamoDbTable<EventRecord> getTable() {
      return dynamodb.table(tableName, TableSchema.fromBean(EventRecord.class));
  }

我这样试过,并没有抛出异常。

  @Test
  public void getEvent_null_notFound() {
    String userId = UUID.randomUUID().toString();
    String eventId = UUID.randomUUID().toString();
    DynamoDbTable dynamoDbTable = mock(DynamoDbTable.class);

    EventRecord  event = null;
    when(dynamoDbTable.getItem(any(GetItemEnhancedRequest.class))).thenReturn(event);

    assertEquals(event, dynamoDbTable.getItem(event));
  }

请注意,我嘲笑 DynamoDbTable 而不是 DynamoDbEnhancedClient

模拟调用客户端并对您自己的代码进行单元测试当然是个好主意,但如果您想使用本地数据库进行实际的 DyanmoDb 调用,我强烈建议您使用本地 dynamodb 库。

此处已满documentation。如果您在单元测试中使用此库,则无需模拟调用。