模拟和单元测试此方法的最佳方式,该方法具有静态生成器



我有以下需要测试的私有函数(针对这个问题进行了简化):

private AmazonS3 getAmazonS3Client(boolean supportsEncryption) {
AmazonS3 amazonS3;
if (supportsEncryption) {
amazonS3 = AmazonS3EncryptionClientBuilder
.standard()
.withRegion(...)
.withCredentials(...))
.withEncryptionMaterials(...)
.build();
} else {
amazonS3 = AmazonS3ClientBuilder
.standard()
.withRegion(...)
.withCredentials(...)
.build();
}
return amazonS3;
}

我从另一个传递supportsEncryption值的公共函数调用此函数。

我如何模拟这些静态构建器方法,以便测试这个分支代码是否正确工作?或者,组织这些代码以使其更易于测试的好方法是什么

将那些静态实现关注点封装在可以模拟的抽象后面。

public interface AmazonS3ClientBuilderService  {
AmazonS3 buildClient();
AmazonS3 buildEncryptedClient();
}

该接口的实现将封装静态生成器方法

public class DefaultAmazonS3ClientBuilderService implements AmazonS3ClientBuilderService {
public AmazonS3 buildClient() {
return AmazonS3ClientBuilder
.standard()
.withRegion(...)
.withCredentials(...)
.build();
}
public AmazonS3 buildEncryptedClient() {
return AmazonS3EncryptionClientBuilder
.standard()
.withRegion(...)
.withCredentials(...))
.withEncryptionMaterials(...)
.build();
}
}

重构目标代码依赖于抽象而非具体

private AmazonS3ClientBuilderService clientBuilder; // To be populated via injection.
private AmazonS3 getAmazonS3Client(boolean supportsEncryption) {
AmazonS3 amazonS3;
if (supportsEncryption) {
amazonS3 = clientBuilder.buildEncryptedClient();
} else {
amazonS3 = clientBuilder.buildClient();
}
return amazonS3;
}

目标类应该通过构造函数注入遵循显式依赖性原则。这将允许在隔离测试时替换抽象,无论是通过自定义实现还是模拟框架。

最新更新