Home > other >  Write Service Test abount Amazon s3 for Junit of Spring Boot
Write Service Test abount Amazon s3 for Junit of Spring Boot

Time:10-26

I have a problem about writing junit test for this service shown below. I wrote some methods but only one cannot work.

How can I fix it?

Here is the service shown below.

public class AmazonStoreService {
    private final AmazonS3 amazonS3;
    private final String BUCKET_NAME = "bucketname";
    private String baseUrl ="baseUrl";

    public String uploadImg(File file, Long id) {
        amazonS3.putObject(BUCKET_NAME, id.toString(), file);
        return baseUrl   bookId;
    }

    public void deleteImg(Long id) {
        amazonS3.deleteObject(BUCKET_NAME, id.toString());
    }

    public String getImgUrl(Long id) {
        return baseUrl   id;
    }
}

Here is the AmazonServiceTest class shown below.

class AmazonServiceTest extends BaseServiceTest{

@InjectMocks
AmazonStoreService imageStoreService;

@Mock
AmazonS3 amazonS3;

private final String BUCKET_NAME = "bucketname";
private String baseUrl = "baseUrl";

@Test
void givenBookIdAndFile_thenReturnBaseUrlOfImage() {

    // given - precondition or setup
    Long bookId = 1L;
    String fileName = "sample.png";
    MockMultipartFile uploadFile =
            new MockMultipartFile("file", fileName, "image/png", "Some bytes".getBytes());

    File file = convert(uploadFile);

    // when -  action or the behaviour that we are going test
    doNothing().when(amazonS3).putObject(BUCKET_NAME,bookId.toString(), file);

    // then - verify the output
    imageStoreService.uploadImg(file,bookId);

    verify(imageStoreService, times(1)).uploadImg(any(File.class), any(Long.class));
}

@Test
void givenBookId_thenDeleteImageOfBook() {

    // given - precondition or setup
    Long bookId = 1L;

    // when -  action or the behaviour that we are going test
    doNothing().when(amazonS3).deleteObject(BUCKET_NAME,bookId.toString());

    // then - verify the output
    imageStoreService.deleteImg(1L);

    verify(amazonS3, times(1)).deleteObject(BUCKET_NAME,bookId.toString());
}

@Test
void givenBookId_tenReturnBaseUrlOfImage() {

    // given - precondition or setup
    Long bookId = 1L;

    String expected = baseUrl   bookId;

    // when -  action or the behaviour that we are going test

    // then - verify the output
    String result = imageStoreService.getImgUrl(1L);

    assertEquals(expected, result);

}

private File convert(final MultipartFile multipartFile) {
    // convert multipartFile to File
    File file = new File(Objects.requireNonNull(multipartFile.getOriginalFilename()));
    try (FileOutputStream fos = new FileOutputStream(file)) {
        fos.write(multipartFile.getBytes());
        return file;
    } catch (IOException e) {
        throw new RuntimeException("Failed to convert multipartFile to File : "   e);
    }
}

}

Here is the error throwing from first test method named givenBookIdAndFile_thenReturnBaseUrlOfImage

org.mockito.exceptions.base.MockitoException: 
Only void methods can doNothing()!
Example of correct use of doNothing():
    doNothing().
    doThrow(new RuntimeException())
    .when(mock).someVoidMethod();
Above means:
someVoidMethod() does nothing the 1st time but throws an exception the 2nd time is called

CodePudding user response:

You can mock AmazonS3 object by writing something like this:

AmazonS3 mockObject;
@Before
public void setup() {
    mockObject = Mockito.mock(AmazonS3.class);
    doNothing().when(mockObject).putObject(anyString(), any());
    doNothing().when(mockObject).deleteObject(anyString(), anyLong());
}

Also you would need to find a way to inject this mockObject into your AmazonStoreService class.

Another way to mock is to use MockAnnotation

@Mock AmazonS3 mockObject;
@Before
public void setup() {
    MockitoAnnotations.openMocks(this)
    doNothing().when(mockObject).putObject(anyString(), any());
    doNothing().when(mockObject).deleteObject(anyString(), anyLong());
}
  • Related