我编写了以下代码来发布有关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
的错误。
其次,我有使用特定参数调用的私有方法。
问题是
如何对此代码进行单元测试?我在某处读到,如果代码不可进行单元测试,那么它就是一个糟糕的设计。如何改进此代码以使其易于测试?我更愿意将这些帮助程序方法保留为
private
方法。如何模拟
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 类中,在那里您可以正确注入依赖项、管理生命周期等。