我想在Java中模拟DataClient类的一个对象。我不确定如何在这里模拟 s3 成员变量。我来自 ruby 背景,我们有一个名为 rspec-mock 的东西,我们不需要模拟实例变量。
public class DataClient {
private String userName, bucket, region, accessKey, secretKey;
private AmazonS3Client s3;
public OdwClient(String accessKey, String secretKey, String userName, String bucket, String region){
this.accessKey = accessKey;
this.accessKey = secretKey;
this.userName = userName;
this.bucket = bucket;
this.region = region;
this.s3 = new AmazonS3Client(new BasicAWSCredentials(accessKey, secretKey));
}
public boolean pushData(String fileName) {
s3.putObject(new PutObjectRequest("bucketName", fileName, new File("filePath")).
return true;
}
}
我现在尝试的只是在测试中是:
@Before
public void setUp() throws Exception{
DataClient client = Mockito.mock(DataClient.class);
}
@Test
public void testPushData() {
// I don't know how to mock s3.putObject() method here
}
我的测试一直失败。
您遇到的问题是因为您没有使用依赖注入。模拟背后的整个思想是,你为外部依赖项创建模拟对象。为此,您需要为对象提供这些外部依赖项。这可以作为构造函数参数或参数,或通过依赖注入框架完成。
下面介绍了如何重写类以使其更易于测试:
public class DataClient {
private String userName, bucket, region, accessKey, secretKey;
private AmazonS3Client s3;
public OdwClient(String accessKey, String secretKey, String userName, String bucket, String region){
this(accessKey, secretKey, userName, bucket, region, new AmazonS3Client(new BasicAWSCredentials(accessKey, secretKey));
}
public OdwClient(String accessKey, String secretKey, String userName, String bucket, String region, AmazonS3Client s3){
this.accessKey = accessKey;
this.accessKey = secretKey;
this.userName = userName;
this.bucket = bucket;
this.region = region;
this.s3 = s3;
}
public boolean pushData(String fileName) {
s3.putObject(new PutObjectRequest("bucketName", fileName, new File("filePath")).
return true;
}
}
然后,您可以使用真实的DataClient
实例而不是模拟,并为新的 DataClient 构造函数模拟 s3 实例。模拟AmazonS3Client
实例后,您可以使用典型的模拟工具来提供来自其方法的预期响应。
您可以使用 PowerMock 扩展来模拟 AmazonS3Client 类的实例化。 沿着这条线的东西
myMockedS3Client = Mockito.mock(AmazonS3Client.class)
PowerMockito.whenNew(AmazonS3Client.class).thenReturn(myMockedS3Client)