Spring Boot Application with Jersey Rest End Points

Yesterday I received a requirement to create a JAVA Spring Boot Application with Jersey Rest end-points. Researching on Internet about how to overwrite the SB configuration I founded that it solves with only one dependency!

So, here is a little example about how to configure and test (with Mockito and EasyMock) a Jersey end-point in a Spring Boot Application.

Steps/Tips

Add the Spring Boot starter Maven dependency for Jersey to your pom.xml

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

Add the configuration bean to include the Jersey’s Controller (classes or packages)

package com.example.sb.jersey.config;

import org.glassfish.jersey.server.ResourceConfig;
import org.springframework.context.annotation.Configuration;

import com.example.sb.jersey.controller.ExampleController;

/**
 * Configuration class for Jersey controllers.
 * @author Gabriel
 *
 */
@Configuration
public class JerseyAppConfig extends ResourceConfig {
    public JerseyAppConfig() {
    	// you can map the packages
    	// packages("com.example.sb.jersey");
    	// or you can map each controller
        register(ExampleController.class);
    }
}

Replace the default Spring Boot annotations with Jersey annotations for the rest end-points

package com.example.sb.jersey.controller;

import java.util.Map;

import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Component;

import com.example.sb.jersey.service.ExampleService;

/**
 * Handles the resource requests.
 * @author Gabriel
 *
 */
@Component
@Path("/resources")
public class ExampleController {

	private static final Logger LOGGER = LoggerFactory.getLogger(ExampleController.class);
	
	@Autowired
	private ExampleService exampleService;
	
	/**
	 * Gets a list of configured resources (queues and/or topics) for the application.
	 * @return
	 */
	@GET
	@Produces(MediaType.APPLICATION_JSON_VALUE)
	@Path("/get/test")
	public ResponseEntity<Map<String,String>> getConfiguredResources() {
		LOGGER.info("getConfiguredResources - start");
		
		Map<String,String> configuredResources = exampleService.getConfiguredResources();
		
		LOGGER.info("getConfiguredResources - end");
		return new ResponseEntity<Map<String,String>>(configuredResources, HttpStatus.OK);
	}
}

Unit Test for the Controller with Mockito for Spring Boot 1.4 or higer

package com.example.sb.jersey.controller;

import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import org.junit.runner.RunWith;
import org.mockito.Mockito;
import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.boot.test.mock.mockito.SpyBean;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.test.context.junit4.SpringRunner;

import com.example.sb.jersey.controller.ExampleController;
import com.example.sb.jersey.service.ExampleService;

import static org.hamcrest.MatcherAssert.assertThat;

import java.util.HashMap;
import java.util.Map;

import static org.hamcrest.CoreMatchers.notNullValue;
import static org.hamcrest.CoreMatchers.nullValue;
import static org.hamcrest.CoreMatchers.equalTo;

@RunWith(SpringRunner.class)
public class ExampleControllerTest {

	@Rule
	public ExpectedException thrown = ExpectedException.none();
	
	@MockBean
	ExampleService exampleServiceMock;
	
	@SpyBean // use inject mocks with spring boot versions lower than 1.4
	private ExampleController exampleController;
	
	private Map<String, String> configuredResources;
	
	@Before
	public void setUp() {
		configuredResources = new HashMap<>();
		configuredResources.put("1", "resource #1");
		configuredResources.put("2", "resource #2");
		configuredResources.put("3", "resource #3");
		configuredResources.put("4", "resource #4");
		configuredResources.put("5", "resource #5");
	}
	
	@Test
	public void getConfiguredResourcesWithValidArgumentsShouldReturnAResponseEntityWithListOfConfiguredResources() {
		Mockito.doReturn(configuredResources).when(exampleServiceMock).getConfiguredResources();
		
		ResponseEntity<Map<String,String>> result = exampleController.getConfiguredResources();
		
		assertThat(result, notNullValue());
		assertThat(result.getStatusCode(), equalTo(HttpStatus.OK));
		assertThat(result.getBody(), notNullValue());
		assertThat(result.getBody().size(), equalTo(configuredResources.size()));
	}
	
	@Test
	public void getConfiguredResourcesWithValidArgumentsShouldReturnAResponseEntityWithNullListOfConfiguredResources() {
		Mockito.doReturn(null).when(exampleServiceMock).getConfiguredResources();
		
		ResponseEntity<Map<String,String>> result = exampleController.getConfiguredResources();
		
		assertThat(result, notNullValue());
		assertThat(result.getStatusCode(), equalTo(HttpStatus.OK));
		assertThat(result.getBody(), nullValue());
	}

	@Test
	public void getConfiguredResourcesWithValidArgumentsShouldReturnAResponseEntityWithEmptyListOfConfiguredResources() {
		Mockito.doReturn(new HashMap<>()).when(exampleServiceMock).getConfiguredResources();
		
		ResponseEntity<Map<String,String>> result = exampleController.getConfiguredResources();
		
		assertThat(result, notNullValue());
		assertThat(result.getStatusCode(), equalTo(HttpStatus.OK));
		assertThat(result.getBody(), notNullValue());
		assertThat(result.getBody().size(), equalTo(0));
	}	
}

Unit Test for the Controller with Mockito for Spring Boot 1.3.8 or lower

package com.example.sb.jersey.controller.oldmockito;

import org.junit.Before;
import org.junit.Test;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.MockitoAnnotations;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;

import com.example.sb.jersey.controller.ExampleController;
import com.example.sb.jersey.service.ExampleService;

import static org.hamcrest.MatcherAssert.assertThat;

import java.util.HashMap;
import java.util.Map;

import static org.hamcrest.CoreMatchers.notNullValue;
import static org.hamcrest.CoreMatchers.nullValue;
import static org.hamcrest.CoreMatchers.equalTo;

public class ExampleControllerTest {

	@Mock
	ExampleService exampleServiceMock;
	
	@InjectMocks // use inject mocks with spring boot versions lower than 1.4
	private ExampleController exampleController = new ExampleController();
	
	private Map<String, String> configuredResources;
	
	@Before
	public void setUp() {
		configuredResources = new HashMap<>();
		configuredResources.put("1", "resource #1");
		configuredResources.put("2", "resource #2");
		configuredResources.put("3", "resource #3");
		configuredResources.put("4", "resource #4");
		configuredResources.put("5", "resource #5");
		
		MockitoAnnotations.initMocks(this);
	}
	
	@Test
	public void getConfiguredResourcesWithValidArgumentsShouldReturnAResponseEntityWithListOfConfiguredResources() {
		Mockito.doReturn(configuredResources).when(exampleServiceMock).getConfiguredResources();
		
		ResponseEntity<Map<String,String>> result = exampleController.getConfiguredResources();
		
		assertThat(result, notNullValue());
		assertThat(result.getStatusCode(), equalTo(HttpStatus.OK));
		assertThat(result.getBody(), notNullValue());
		assertThat(result.getBody().size(), equalTo(configuredResources.size()));
	}
	
	@Test
	public void getConfiguredResourcesWithValidArgumentsShouldReturnAResponseEntityWithNullListOfConfiguredResources() {
		Mockito.doReturn(null).when(exampleServiceMock).getConfiguredResources();
		
		ResponseEntity<Map<String,String>> result = exampleController.getConfiguredResources();
		
		assertThat(result, notNullValue());
		assertThat(result.getStatusCode(), equalTo(HttpStatus.OK));
		assertThat(result.getBody(), nullValue());
	}

	@Test
	public void getConfiguredResourcesWithValidArgumentsShouldReturnAResponseEntityWithEmptyListOfConfiguredResources() {
		Mockito.doReturn(new HashMap<>()).when(exampleServiceMock).getConfiguredResources();
		
		ResponseEntity<Map<String,String>> result = exampleController.getConfiguredResources();
		
		assertThat(result, notNullValue());
		assertThat(result.getStatusCode(), equalTo(HttpStatus.OK));
		assertThat(result.getBody(), notNullValue());
		assertThat(result.getBody().size(), equalTo(0));
	}	
}

Unit Test for the Controller with EasyMock 3.4

package com.example.sb.jersey.service.easymock;

import org.easymock.EasyMockRunner;
import org.easymock.TestSubject;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;

import com.example.sb.jersey.service.ExampleService;

import java.util.HashMap;
import java.util.Map;

import static org.hamcrest.CoreMatchers.notNullValue;
import static org.hamcrest.CoreMatchers.equalTo;
import static org.hamcrest.MatcherAssert.assertThat;

@RunWith(EasyMockRunner.class)
public class ResourceServiceTest {

	@TestSubject
	private ExampleService exampleService = new ExampleService();
	
	private Map<String, String> configuredResources;
	
	@Before
	public void setUp() {
		configuredResources = new HashMap<>();
		configuredResources.put("1", "resource #1");
		configuredResources.put("2", "resource #2");
		configuredResources.put("3", "resource #3");
	}
	
	@Test
	public void getConfiguredResourcesWithValidArgumentsShouldReturnAResponseEntityWithListOfConfiguredResources() {
		Map<String,String> result = exampleService.getConfiguredResources();
		
		assertThat(result, notNullValue());
		assertThat(result.size(), equalTo(configuredResources.size()));
	}
}

 

Final notes
The application was tested with Spring Boot versions: 1.5.3.RELEASE, 1.4.2.RELEASE and 1.3.8.RELEASE (without ServletInitiliazer class)

You can get the complete code from my public GitHub repository. Please, comment or contact me if you have any issue or new ideas about this post.

Also you can find me at Upwork

See you soon with more development notes…


Comments

One response to “Spring Boot Application with Jersey Rest End Points”

  1. Elena Mays Avatar
    Elena Mays

    Useful information. Lucky me I discovered your website by accident, and I am stunned why this accident didn’t came about earlier! I bookmarked it.

    Like

Leave a comment