How to write JUnit for the following Code to read Azure Blob

179 Views Asked by At

Below is code implementation for reading an azure blob , i am getting exception java.io.IOException: Underlying input stream returned zero bytes for the line reader.readLine() in while condition. Following are my codes that i have tried

@Component
@AllArgsConstructor
@Slf4j
public class AzureBlobServiceImpl implements AzureBlobService {

    BlobServiceClient blobServiceClient;

    AzureStorageConfiguration azureStorageConfiguration;
    DownloadRetryOptions downloadRetryOptions;

    
    @Override
    public List<String> readBlobFile(String container) {
        BlobContainerClient blobContainerClient = blobServiceClient.getBlobContainerClient(container);
        Stream<BlobItem> blobItemsStream = blobContainerClient.listBlobs().stream();
        List<String> fileList = new ArrayList<>();
        Pattern pattern = Pattern.compile(azureStorageConfiguration.getInputFilePattern());
        if (pattern != null) {
            blobItemsStream = blobItemsStream.filter((blobItem) -> pattern.asPredicate().test(blobItem.getName()));
        }
        blobItemsStream.forEach((blobItem) -> {
            log.info("blob found {} in the container {} with creation time {} & last modified time {}", blobItem.getName(),container,
                    blobItem.getProperties().getCreationTime(),blobItem.getProperties().getLastModified());
            BlobClient blobClient = blobContainerClient.getBlobClient(blobItem.getName());
            try (BufferedReader reader = new BufferedReader(new InputStreamReader(blobClient.openInputStream()))) {
                String line;
                long row = 1;
                while ((line = reader.readLine()) != null) {
                    log.info("Row  {} : {}",row, line);
                    //TODO write logic to insert each row in the table
                    row++;
                }
            } catch (BlobStorageException e) {
                log.error("error while reading the file {}",blobItem.getName(),e);
                throw new BlobReadingException("Error while reading " + blobItem.getName() +e);
            }catch (Exception e) {
                throw new BlobReadingException("Error occurred while processing " + blobItem.getName()+ e);
            }
            fileList.add(blobItem.getName());
            //Archive the files and delete from inboud
            archiveFile(blobItem.getName());
        });
        log.info("fileList: "+fileList);

        return fileList;
    } Following is my JUnit for the above 

@ExtendWith(MockitoExtension.class)
class AzureBlobServiceImplTest {

    @Mock
    BlobServiceClient blobServiceClient;

    @Mock
    DownloadRetryOptions downloadRetryOptions;

    @Mock
    AzureStorageConfiguration azureStorageConfiguration;

    @Mock
    BlobContainerClient blobContainerClient;
    @Mock
    BlobClient blobClient;

    @Mock
    Response<Boolean> response;

    @Mock
    BlobDownloadResponse blobDownloadResponse;

    @Mock
    BlobInputStream blobInputStream;

    @Mock
    PagedIterable<BlobItem> iterable;

    @Mock
    BufferedReader bufferedReader;

    @InjectMocks
    AzureBlobServiceImpl azureBlobService;


    @BeforeEach
    void setUp() {
        Assertions.assertNotNull(azureBlobService);
        when(blobServiceClient.getBlobContainerClient(anyString())).thenReturn(blobContainerClient);
        when(blobContainerClient.getBlobClient(anyString())).thenReturn(blobClient);
    }

    @AfterEach
    void testMethodTearDown() {
        Mockito.clearInvocations(blobServiceClient, downloadRetryOptions, azureStorageConfiguration, blobContainerClient, blobClient, response, blobDownloadResponse);
    }

    @Test
    void read_success() throws IOException {

        //String filePath = "src/test/resources/Test25Oct.txt";

       // blobClient.uploadFromFile(filePath);

        ByteArrayOutputStream buffer = new ByteArrayOutputStream();
        BufferedReader input =
                new BufferedReader(new InputStreamReader(new ByteArrayInputStream(buffer.toByteArray())));
        String line = input.readLine();

        BlobItemProperties blobProps = new BlobItemProperties();
        OffsetDateTime offsetDateTime = OffsetDateTime.of(2023, 10, 31, 0, 0, 0, 0, ZoneOffset.UTC);
        blobProps.setCreationTime(offsetDateTime);
        blobProps.setLastModified(offsetDateTime);
        blobProps.setContentLength(100L);
        byte[] dummyData = {1,2,3,5};
        blobProps.setContentMd5(dummyData);

        BlobItem blobItem1 = new BlobItem();
        blobItem1.setName("blob1.txt");
        blobItem1.setProperties(blobProps);

        BlobItem blobItem2 = new BlobItem();
        blobItem2.setName("blob2.txt");
        blobItem2.setProperties(blobProps);

        List<BlobItem> blobItemList = List.of(blobItem1, blobItem2);

        when(blobServiceClient.getBlobContainerClient(anyString())).thenReturn(blobContainerClient);
        when(blobContainerClient.listBlobs()).thenReturn(iterable);
        when(blobContainerClient.listBlobs().stream()).thenReturn(blobItemList.stream());
        when(blobContainerClient.getBlobClient(anyString())).thenReturn(blobClient);
        when(bufferedReader.readLine())
                .thenReturn("Line 1")
                .thenReturn("Line 2")
                .thenReturn(null);
        when(blobClient.openInputStream()).thenReturn(blobInputStream);
        when(azureStorageConfiguration.getInputFilePattern()).thenReturn(".*blob.*");
        //test the method
        List<String> fileList = azureBlobService.readBlobFile("test-container");

        assertEquals(2, fileList.size());
        assertEquals("blob1.txt", fileList.get(0));
        assertEquals("blob2.txt", fileList.get(1));

        verify(blobServiceClient, times(1)).getBlobContainerClient("test-container");
        verify(blobContainerClient, times(2)).listBlobs();
        verify(blobContainerClient, times(2)).getBlobClient(anyString());
        verify(blobClient, times(2)).openInputStream();
    }
}

Can someone please help on how i can mock the behaviour to return InoutStream for my Test class?

0

There are 0 best solutions below