Junit Testing Of File Upload And Download

Junit Test

Here in this tutorial you will see examples on Junit testing of file upload and download in Spring REST Controllers. You might have seen how to write Junit test cases on Spring REST Controllers in my other tutorials but I did not show how to write Junit testing of file upload and download in Spring REST Controllers but here you will see those in action.

I will use here spring-boot-starter-test artifact to test the upload and download functionalities.

You may also check my other Junit Tutorials.

Let’s move on to the example…

Prerequisites

Knowledge of Junit, Java

File Upload example using Spring REST Controller

File Download example using REST Controller

I will use Spring framework’s MultipartFile to upload a file and when you download a file you send byte[] as a response OutputStream so that file will be forcefully downloaded and user will be given option for saving the downloaded file.

Here I will not create a separate project and I will create separate Junit class for Junit testing of file upload and download in Spring REST Controllers in their respective project.

Setting up a project

In your existing gradle or maven based Java project add the below dependencies for Junit in build.gradle script or pom.xml file:

testImplementation("org.springframework.boot:spring-boot-starter-test")

Or

<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-test</artifactId>
</dependency>

Junit classes

Now in src/test/java directory under the package com.roytuts.spring.rest.file.upload.controller, create below Junit test class for testing upload functionality:

package com.roytuts.spring.rest.file.upload.controller;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;

import java.io.InputStream;

import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.junit.jupiter.MockitoExtension;
import org.springframework.http.MediaType;
import org.springframework.mock.web.MockMultipartFile;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.MvcResult;
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
import org.springframework.test.web.servlet.result.MockMvcResultMatchers;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;

@ExtendWith(MockitoExtension.class)  //optional
public class FileUploadControllerTest {

	private InputStream is;

	private MockMvc mockMvc;

	private FileUploadRestController controller = new FileUploadRestController();

	@BeforeEach
	public void init() {
		mockMvc = MockMvcBuilders.standaloneSetup(controller).build();
		is = controller.getClass().getClassLoader().getResourceAsStream("certificate.pdf");
	}

	@Test
	public void testUploadFile() throws Exception {
		MockMultipartFile mockMultipartFile = new MockMultipartFile("file", "certificate.pdf", "multipart/form-data",
				is);

		MvcResult result = mockMvc
				.perform(MockMvcRequestBuilders.multipart("/upload").file(mockMultipartFile)
						.contentType(MediaType.MULTIPART_FORM_DATA))
				.andExpect(MockMvcResultMatchers.status().is(200)).andReturn();

		assertEquals(200, result.getResponse().getStatus());
		assertNotNull(result.getResponse().getContentAsString());
		assertEquals("certificate.pdf", result.getResponse().getContentAsString());
	}

}

I run the test class with MockitoExtension class. You also need to put a file under the src/test/resources folder to test the file upload functionality. You can put any type of file and you can change the file name in the above test class according to your file name.

For file download functionality, write the following class under src/test/java class path folder.

package com.roytuts.spring.rest.file.download.controller;

import static org.junit.jupiter.api.Assertions.assertEquals;

import java.util.ArrayList;

import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.junit.jupiter.MockitoExtension;
import org.springframework.http.MediaType;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.MvcResult;
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
import org.springframework.test.web.servlet.result.MockMvcResultMatchers;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;

import com.roytuts.spring.rest.file.download.service.EmployeeService;

@ExtendWith(MockitoExtension.class)
public class FileDownloadControllerTest {

	private MockMvc mockMvc;

	@Mock
	private EmployeeService employeeService;

	@InjectMocks
	private FileDownloadRestController controller = new FileDownloadRestController();

	@BeforeEach
	public void init() {
		mockMvc = MockMvcBuilders.standaloneSetup(controller).build();
	}

	@Test
	public void testDownloadFile() throws Exception {
		Mockito.when(employeeService.getEmployees()).thenReturn(new ArrayList<>());

		MvcResult result = mockMvc
				.perform(MockMvcRequestBuilders.get("/download").contentType(MediaType.APPLICATION_OCTET_STREAM))
				.andExpect(MockMvcResultMatchers.status().is(200)).andReturn();

		assertEquals(200, result.getResponse().getStatus());
		assertEquals(2, result.getResponse().getContentAsByteArray().length);
		assertEquals("text/json", result.getResponse().getContentType());
	}

}

I mock the service and inject into the controller class. I only create actual object for the controller class for which I am going to check the functionality through Junit test cases.

I inject all other mock services into this class object using @InjectMocks annotation. I perform all initialization tasks in init() method and this method must be annotated with @BeforeEach in order to execute any test case.

Next I put annotations for all the test methods and run the test case for each functionality of the controller method.

Notice how I have mocked the MultipartFile object and test the upload functionality and check the final response.

Testing Test Cases

Now run the above Junit test class and you should see the success results for test cases.

2 thoughts on “Junit Testing Of File Upload And Download

Leave a Reply

Your email address will not be published. Required fields are marked *