简体   繁体   English

在 AmazonS3 中使用 junit 和 mockito 对 getObject 方法进行单元测试

[英]Unit test using junit and mockito for getObject method in AmazonS3

I have method which uses s3.getObject to get S3Object and writes the contents of the object into a temporary file我有使用 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();
    }

I'm not sure I understand how to write the unit test for this method.我不确定我是否了解如何为此方法编写单元测试。 Here is what I have tried这是我尝试过的

@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));
    }

I'm new to unit tests and I'm not sure what I can assert here since I'm getting only an absolute path of the file from the method.我是单元测试的新手,我不确定我可以在这里断言什么,因为我只从方法中获取文件的绝对路径。 Can someone advice me on this?有人可以建议我吗?

There are a few things I would suggest changing in the test Do not mock the S3Object rather build the object from a local file, setting the value to the mocked object isn't correct.我建议在测试中更改一些内容不要模拟S3Object ,而是从本地文件构建对象,将值设置为模拟对象是不正确的。

You should add tests for exceptions as well.您还应该为异常添加测试。

Check out the below code看看下面的代码

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;
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM