使用 junit 和 mockito 对 AmazonS3 中的 getObject 方法进行单元测试
Unit test using junit and mockito for getObject method in AmazonS3
我有使用 s3.getObject 获取 S3Object 并将对象的内容写入临时文件的方法
@Override
public Optional<String> getObject(String s3BucketName, String s3Path) {
try {
S3Object s3Object = s3Client.getObject(new GetObjectRequest(s3BucketName, s3Path));
try (S3ObjectInputStream s3ObjectInputStream = s3Object.getObjectContent()){
File tmp = File.createTempFile("/tmp/" + UUID.randomUUID().toString(), ".json");
IOUtils.copy(s3ObjectInputStream, new FileOutputStream(tmp));
return Optional.of(tmp.getAbsolutePath());
} catch (Exception e) {
System.err.println(e.getMessage());
}
} catch (AmazonServiceException e) {
String msg = String.format("Service error while getting object=%s in bucket=%s",
s3Path, s3BucketName);
throw new RuntimeException(msg, e);
} catch (SdkClientException e) {
String msg = String.format("Client error while getting object=%s in bucket=%s",
s3Path, s3BucketName);
throw new RuntimeException(msg + e.getMessage());
}
return Optional.empty();
}
我不确定我是否了解如何为此方法编写单元测试。这是我试过的
@Test
public void getObjectTest() throws UnsupportedEncodingException {
S3Object s3Object = Mockito.mock(S3Object.class);
s3Object.setObjectContent(new StringInputStream(TEST_STRING));
Mockito.when(mockS3Client.getObject(new GetObjectRequest(TEST_S3BUCKET, TEST_S3OBJECT))).thenReturn(s3Object);
s3Accessor.getObject(TEST_S3BUCKET, TEST_S3OBJECT);
verify(mockS3Client).getObject(new GetObjectRequest(TEST_S3BUCKET, TEST_S3OBJECT));
}
我是单元测试的新手,我不确定我可以在这里断言什么,因为我从该方法中只获得了文件的绝对路径。
有人可以就此给我建议吗?
我建议在测试中更改一些内容
不要模拟 S3Object
而是从本地文件构建对象,将值设置为模拟对象是不正确的。
您还应该添加异常测试。
查看下面的代码
import com.amazonaws.AmazonServiceException;
import com.amazonaws.services.s3.AmazonS3Client;
import com.amazonaws.services.s3.model.GetObjectRequest;
import com.amazonaws.services.s3.model.S3Object;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.junit.MockitoJUnitRunner;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.UnsupportedEncodingException;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertThrows;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
@RunWith(MockitoJUnitRunner.class)
public class ExampleServiceTest {
@Mock
private AmazonS3Client mockS3Client;
@Test
public void getObjectTest() throws UnsupportedEncodingException, FileNotFoundException {
String testBucketName = "test_bucket", s3Path = "/files/A.json";
S3Object s3Object = buildS3Object();
when(mockS3Client.getObject(new GetObjectRequest(testBucketName, s3Path))).thenReturn(s3Object);
ExampleService exampleService = new ExampleService(mockS3Client);
exampleService.getObject(testBucketName, s3Path);
verify(mockS3Client).getObject(new GetObjectRequest(testBucketName, s3Path));
}
@Test
public void ShouldThrowRuntimeExceptionServiceErrorMessageWhenAmazonServiceException() throws FileNotFoundException {
String testBucketName = "test_bucket", s3Path = "/files/A.json";
when(mockS3Client.getObject(new GetObjectRequest(testBucketName, s3Path))).thenThrow(AmazonServiceException.class);
ExampleService exampleService = new ExampleService(mockS3Client);
Exception exception = assertThrows(RuntimeException.class, () -> {
exampleService.getObject(testBucketName, s3Path);
});
assertEquals("Service error while getting object=/files/A.json in bucket=test_bucket", exception.getMessage());
}
private S3Object buildS3Object() throws FileNotFoundException {
S3Object s3Object = new S3Object();
s3Object.setObjectContent(new FileInputStream("your_path/src/test/resources/A.json"));
return s3Object;
}
}
我有使用 s3.getObject 获取 S3Object 并将对象的内容写入临时文件的方法
@Override
public Optional<String> getObject(String s3BucketName, String s3Path) {
try {
S3Object s3Object = s3Client.getObject(new GetObjectRequest(s3BucketName, s3Path));
try (S3ObjectInputStream s3ObjectInputStream = s3Object.getObjectContent()){
File tmp = File.createTempFile("/tmp/" + UUID.randomUUID().toString(), ".json");
IOUtils.copy(s3ObjectInputStream, new FileOutputStream(tmp));
return Optional.of(tmp.getAbsolutePath());
} catch (Exception e) {
System.err.println(e.getMessage());
}
} catch (AmazonServiceException e) {
String msg = String.format("Service error while getting object=%s in bucket=%s",
s3Path, s3BucketName);
throw new RuntimeException(msg, e);
} catch (SdkClientException e) {
String msg = String.format("Client error while getting object=%s in bucket=%s",
s3Path, s3BucketName);
throw new RuntimeException(msg + e.getMessage());
}
return Optional.empty();
}
我不确定我是否了解如何为此方法编写单元测试。这是我试过的
@Test
public void getObjectTest() throws UnsupportedEncodingException {
S3Object s3Object = Mockito.mock(S3Object.class);
s3Object.setObjectContent(new StringInputStream(TEST_STRING));
Mockito.when(mockS3Client.getObject(new GetObjectRequest(TEST_S3BUCKET, TEST_S3OBJECT))).thenReturn(s3Object);
s3Accessor.getObject(TEST_S3BUCKET, TEST_S3OBJECT);
verify(mockS3Client).getObject(new GetObjectRequest(TEST_S3BUCKET, TEST_S3OBJECT));
}
我是单元测试的新手,我不确定我可以在这里断言什么,因为我从该方法中只获得了文件的绝对路径。 有人可以就此给我建议吗?
我建议在测试中更改一些内容
不要模拟 S3Object
而是从本地文件构建对象,将值设置为模拟对象是不正确的。
您还应该添加异常测试。
查看下面的代码
import com.amazonaws.AmazonServiceException;
import com.amazonaws.services.s3.AmazonS3Client;
import com.amazonaws.services.s3.model.GetObjectRequest;
import com.amazonaws.services.s3.model.S3Object;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.junit.MockitoJUnitRunner;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.UnsupportedEncodingException;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertThrows;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
@RunWith(MockitoJUnitRunner.class)
public class ExampleServiceTest {
@Mock
private AmazonS3Client mockS3Client;
@Test
public void getObjectTest() throws UnsupportedEncodingException, FileNotFoundException {
String testBucketName = "test_bucket", s3Path = "/files/A.json";
S3Object s3Object = buildS3Object();
when(mockS3Client.getObject(new GetObjectRequest(testBucketName, s3Path))).thenReturn(s3Object);
ExampleService exampleService = new ExampleService(mockS3Client);
exampleService.getObject(testBucketName, s3Path);
verify(mockS3Client).getObject(new GetObjectRequest(testBucketName, s3Path));
}
@Test
public void ShouldThrowRuntimeExceptionServiceErrorMessageWhenAmazonServiceException() throws FileNotFoundException {
String testBucketName = "test_bucket", s3Path = "/files/A.json";
when(mockS3Client.getObject(new GetObjectRequest(testBucketName, s3Path))).thenThrow(AmazonServiceException.class);
ExampleService exampleService = new ExampleService(mockS3Client);
Exception exception = assertThrows(RuntimeException.class, () -> {
exampleService.getObject(testBucketName, s3Path);
});
assertEquals("Service error while getting object=/files/A.json in bucket=test_bucket", exception.getMessage());
}
private S3Object buildS3Object() throws FileNotFoundException {
S3Object s3Object = new S3Object();
s3Object.setObjectContent(new FileInputStream("your_path/src/test/resources/A.json"));
return s3Object;
}
}