Expand my Community achievements bar.

Writing a unit test for a servlet that reads an excel file is failing?

Avatar

Level 8

Hi

I am writing a unit test for a servlet that uses an excel file as input stream using the poi library

org.apache.poi

This is the servlet:

 

 

 

 

 

 

 

 

 

protected void doPost(SlingHttpServletRequest request, SlingHttpServletResponse response) throws IOException {
PrintWriter out = response.getWriter();
RequestParameter xlsxFile = request.getRequestParameter("xlsxfile");

final InputStream inputStream = xlsxFile.getInputStream();



try (inputStream) {
Workbook workbook = new XSSFWorkbook(inputStream); // Use XSSFWorkbook for xlsx files

json = extractData(workbook);

} catch (IOException e) {
throw new RuntimeException("Could not parse XLSX file", e);
} 

 

 

 

 

 

 

 

 

 

This is the  Unit Test:

 

 

 

 

 

 

 

void testExcelFileImport() throws IOException {
    InputStream inputStream = MyServlet.class.getResourceAsStream("/component/tools/excel-import/import/excel-data.xlsx");
byte[] bytes = IOUtils.toByteArray(inputStream);

context.request().addRequestParameter("xlsxfile", bytes, "xlsxfile", "excel-file.xlsx");


MockSlingHttpServletRequest request = context.request();
MockSlingHttpServletResponse response = context.response();

underTest.doPost(request, response);
assertEquals("Success: Excel correctly imported as JSON", response.toString())
}

 

 

 

 

 

 

 

 
The unit Test is failing here 2024-05-03 16_41_51-Evaluate.png

 
Updating Media

static_member_of_poiXMLDocumentPart.png

Workbook workbook = new XSSFWorkbook(inputStream)
11 Replies

Avatar

Community Advisor

@anasustic 

 

Can you try below code

 

@Override
protected void doPost(SlingHttpServletRequest request, SlingHttpServletResponse response) throws IOException {
PrintWriter out = response.getWriter();
RequestParameter xlsxFile = request.getRequestParameter("xlsxfile");

final InputStream inputStream = xlsxFile.getInputStream();



try (inputStream) {
Workbook workbook = new XSSFWorkbook(inputStream); // Use XSSFWorkbook for xlsx files

json = extractData(workbook);

} catch (IOException e) {
throw new RuntimeException("Could not parse XLSX file", e);

 

Avatar

Level 8

Hi 

Thanks for answering. My servlet is working correctly. I cannot get the unit test to work correctly.

Avatar

Community Advisor

Hi @anasustic ,

 

Can you please share your complete test class, As I can see you are calling a method with name getResourceAsStream in your test class but can't see the same method in your servlet.

Avatar

Community Advisor

Hi, 

You need to mock the objects and provide your inputStream, try something like the below:

@Mock
SlingHttpServletRequest mockRequest;

... 
InputStream yourFileAsInputStream = ... //Read your file locally and get the InputStream
RequestParameter requestParameterMock = mock(RequestParameter.class):
when(mockRequest.getRequestParameter("xlsxfile").thenReturn(requestParameterMock);
when(requestParameterMock.getInputStream()).thenReturn(yourFileAsInputStream);

underTest.doPost(mockRequest, response);

 

Hope this helps



Esteban Bustamante

Avatar

Level 8

thank for replying. With your code I am getting Cannot resolve method 'thenReturn' in 'RequestParameter'

Avatar

Community Advisor

@anasustic , this happens when the braces are not closed properly. Here below line is causing the issue

when(mockRequest.getRequestParameter("xlsxfile").thenReturn(requestParameterMock);

 updated:

when(mockRequest.getRequestParameter("xlsxfile")).thenReturn(requestParameterMock);

 

Avatar

Community Advisor

I wrote the code on the fly, this is just for reference not for copying/pasting. Please analyze what I am doing and apply it to your code.

 

Thanks @sravs for noting the missing ")". 

Hope this helps



Esteban Bustamante

Avatar

Community Advisor

@anasustic , you are getting error at 

Workbook workbook = new XSSFWorkbook(inputStream)

To execute above line you need to use MockedConstruction with parameters, please refer on how to create mockedConstructor

https://rieckpil.de/mock-java-constructors-and-their-object-creation-with-mockito/

https://www.baeldung.com/java-mockito-mockedconstruction

https://www.baeldung.com/java-mockito-constructors-unit-testing 

Avatar

Level 8

Hi @sravs 

It appears the 

org.apache.poi

I am using in my servlet uses LogManager static methods and I do not have that library in my classpath. How can I mock this? I cannot use mockConstruction. 

private static final Logger LOG = LogManager.getLogger(POIXMLDocumentPart.class);

static_member_of_poiXMLDocumentPart.png

Avatar

Administrator

@anasustic Did you find the suggestions from users helpful? Please let us know if more information is required. Otherwise, please mark the answer as correct for posterity. If you have found out solution yourself, please share it with the community.



Kautuk Sahni