我有以下需要测试的私有函数(针对此问题进行了简化):
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的值。
如何模拟这些静态构建器方法,以便我可以测试此分支代码是否正常工作? 或者,组织此代码以便更容易测试的好方法是什么?
答案 0 :(得分:2)
封装可以模拟的抽象背后的静态实现问题。
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;
}
目标类应该通过构造函数注入遵循显式依赖原则。这将允许在通过自定义实现或模拟框架进行单独测试时替换抽象。