使用 AWS 开发工具包的最终类进行单元测试



我编写了以下代码来发布有关AWS Step 函数(其适用于 AWS 的 java lambda(的一些指标

@Override
public void handleRequest(InputStream input, OutputStream output, Context context) throws IOException {
    int inProgressStateMachines = 0;
    LocalDateTime now = LocalDateTime.now();
    long alarmThreshold = getAlarmThreshold(input, context.getLogger());
    AWSStepFunctions awsStepFunctions = AWSStepFunctionsClientBuilder.standard().build();
    ListStateMachinesRequest listStateMachinesRequest = new ListStateMachinesRequest();
    ListStateMachinesResult listStateMachinesResult = awsStepFunctions.listStateMachines(listStateMachinesRequest);
    for (StateMachineListItem stateMachineListItem : listStateMachinesResult.getStateMachines()) {
        ListExecutionsRequest listExecutionRequest = new ListExecutionsRequest()
                .withStateMachineArn(stateMachineListItem.getStateMachineArn())
                .withStatusFilter(ExecutionStatus.RUNNING);
        ListExecutionsResult listExecutionsResult = awsStepFunctions.listExecutions(listExecutionRequest);
        for (ExecutionListItem executionListItem : listExecutionsResult.getExecutions()) {
            LocalDateTime stateMachineStartTime = LocalDateTime.ofInstant(
                    executionListItem.getStartDate().toInstant(), ZoneId.systemDefault());
            long elapsedTime = ChronoUnit.SECONDS.between(stateMachineStartTime, now);
            if (elapsedTime > alarmThreshold){
                inProgressStateMachines++;
            }
        }
        publishMetrics(inProgressStateMachines);
    }
}

现在我正在尝试对此方法进行单元测试并遇到一些问题。

首先,当我试图嘲笑AWSStepFunctionsClientBuilder时,我得到了Mockito can not mock final class的错误。

其次,我有使用特定参数调用的私有方法。

问题是

  1. 如何对此代码进行单元测试?我在某处读到,如果代码不可进行单元测试,那么它就是一个糟糕的设计。如何改进此代码以使其易于测试?我更愿意将这些帮助程序方法保留为private方法。

  2. 如何模拟AWS SDK中的final对象来测试此代码?我不能使用任何其他框架,但Mockito.

你实际上不想嘲笑AWSStepFunctionsClientBuilder,因为你实际上是在调用AWSStepFunctions,即使在嘲笑构建器之后,你也必须嘲笑它。

因此,AWSStepFunctions是一个实例变量:

// add appropriate getter/setter as well
private AWSStepFunctions awsStepFunctions;

在当前调用构建器初始化awsStepFunctions的位置,更改为:

if (awsStepFunctions == null)
    awsStepFunctions = AWSStepFunctionsClientBuilder.standard().build();

现在,在单元测试期间,您可以绕过上面的条件初始化,将awsStepFunctions设置为模拟实例。

[编辑] 根据@kdgregory下面的评论,还有一些想法:

上面的答案旨在提供给定现有代码结构的解决方案,而无需任何重大重构。一般来说,理想情况下,您希望将大部分代码移动到另一个普通的、更易于测试的 Java 类中,在那里您可以正确注入依赖项、管理生命周期等。

相关内容

  • 没有找到相关文章

最新更新