Testing Jersey Based REST Services with Grizzly


In my last post, we had seen how easy it was to create REST based services with Spring and Jersey. In this post we would quickly see how we can unit test them. Ok, this is not entirely a unit test in the strict sense because we are not testing the resource in isolation but it is a good strategy nevertheless because it helps us to test the resource right from the IDE.

For this, we would include the Grizzly servlet webserver dependency in our pom.xml.

<dependency>
			<groupId>com.sun.grizzly</groupId>
			<artifactId>grizzly-servlet-webserver</artifactId>
			<version>1.9.8</version>
		</dependency>

Once we have the Grizzly server, we would have to power it up at the start of our tests so that the resource can execute inside the container. The test start-up would look like this

@Before
	public void setUp() throws Exception {
		threadSelector = GrizzlyMain.startServer();
		ClientConfig clientConfiguration = new DefaultClientConfig();
		Client client = Client.create(clientConfiguration);
		webresource = client.resource(GrizzlyMain.baseUri);
	}

Also, at the end of every test, we have to terminate the endpoint so that the port is now available for the next test. Hence, we do

	@After
	public void tearDown() throws Exception {
		threadSelector.stopEndpoint();
	}

If you would notice, we have started the GrizzlyServer with GrizzlyMain.startServer(); Let us see what this class looks like

public class GrizzlyMain {
    
    private static int getPort(int defaultPort) {
        String port = System.getenv("JERSEY_HTTP_PORT");
        if (null != port) {
            try {
                return Integer.parseInt(port);
            } catch (NumberFormatException e) {
            }
        }
        return defaultPort;        
    } 
    
    final static URI baseUri = UriBuilder.fromUri( "http://localhost/" ).port( 9998 ).build();
    
    public static SelectorThread startServer() throws IOException{
    	final ServletAdapter adapter =new ServletAdapter();
    	adapter.addInitParameter( "com.sun.jersey.config.property.packages", "com.inphina.sample" );
    	adapter.addInitParameter( "com.sun.jersey.api.json.POJOMappingFeature", "true" );
    	adapter.addContextParameter( "contextConfigLocation","classpath:applicationContext.xml"  );
    	adapter.addServletListener( "org.springframework.web.context.ContextLoaderListener" );
    	adapter.setServletInstance( new SpringServlet() );
    	adapter.setContextPath(baseUri.getPath());
    	adapter.setProperty( "load-on-startup", 1 );

    	System.out.println("********" + baseUri.getPath());
        SelectorThread threadSelector = GrizzlyServerFactory.create(baseUri, adapter);
        return threadSelector;
    }
       
    public static void main(String[] args) throws IOException {
        System.out.println("Starting grizzly...");
        SelectorThread threadSelector = startServer();
        System.out.println(String.format(
                "Jersey app started with WADL available at %sapplication.wadln" +
                "Hit enter to stop it...", baseUri));
        System.in.read();
        threadSelector.stopEndpoint();
    }    
}

As you would notice, the startServer() method, starts the server along with all the details which are present in our web.xml (refer to the last post). Here, we register the SpringServlet and also pass all the init parameters to the servlet. A snapshot of the web.xml is shown here

<servlet>
		<servlet-name>REST</servlet-name>
		<servlet-class>
			com.sun.jersey.spi.spring.container.servlet.SpringServlet</servlet-class>
		<init-param>
			<param-name>com.sun.jersey.config.property.packages</param-name>
			<param-value>com.inphina.social.resources</param-value>
		</init-param>
		<init-param>
			<param-name>com.sun.jersey.api.json.POJOMappingFeature</param-name>
			<param-value>true</param-value>
		</init-param>
		<load-on-startup>1</load-on-startup>
	</servlet>

Now, let us look at a sample test

@Test
	public void getOnHelloWorldPath() {
		// get the initial representation
		String s = webresource.path("helloworld").accept("application/json").get(String.class);
		Assert.assertEquals("{"name":"Vikas Hazrati","age":36,"email":"vhazrati@inphina.com"}", s);
		System.out.println(s);
	}

Here, we make a GET call at the path helloworld and expect a JSON string to be returned which should be equal to what we are expecting. Likewise to make a sample post call you would have a method like this

@Test
	public void testPostLoginJSONFormat() {
		User user = new User();
		user.setEmail("admin");
		user.setPassword("admin");
		Address address = new Address();
		address.setStreet("123");
		user.addAddress(address);

		webresource.path("helloworld").type("application/json").post(user);
		Assert.<something>
	} 

Hence, it is easy to test the REST services with the lightweight Grizzly server in place. The complete code for this and previous post can be accessed here.

Advertisements

About Vikas Hazrati

Vikas is the Founding Partner @ Knoldus which is a group of software industry veterans who have joined hands to add value to the art of software development. Knoldus does niche Reactive and Big Data product development on Scala, Spark and Functional Java. Knoldus has a strong focus on software craftsmanship which ensures high-quality software development. It partners with the best in the industry like Lightbend (Scala Ecosystem), Databricks (Spark Ecosystem), Confluent (Kafka) and Datastax (Cassandra). To know more, send a mail to hello@knoldus.com or visit www.knoldus.com
This entry was posted in Architecture, Java and tagged , , , , . Bookmark the permalink.

One Response to Testing Jersey Based REST Services with Grizzly

  1. ahmed says:

    Thanks for the post. And keep it coming…

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s