понедельник, 23 сентября 2013 г.

Testing RESTful web services

     In my previous article I’ve introduced RESTful web services with JAX-RS library called Jersey, JAXB and Maven. This post show you how to test it with Jersey Test Framework. Let's look at the tools that can help us with that. 
     For testing your RESTful web services with a different request methods, you need a tool that allows you to specify which method to use. So, let’s see to the next popular HTTP client tools.
 - Curl(it’s a command line tool for transferring data via URL). Curl helps you easy to change the HTTP verb that you are using. HTTP GET is the default verb used by curl.
# See all the users in the system on third page 
> curl -X GET http://localhost:8080/RESTfulApp/rest/user/all?page=3
# Create and save new user 
> curl -X POST http://localhost:8080/RESTfulApp/rest/user/create
# Get the information of the user 
> curl -X GET http://localhost:8080/RESTfulApp/rest/user/id/12345
# Update user information 
> curl -X PUT http://localhost:8080/RESTfulApp/rest/user/id/12345
# Delete user
> curl -X DELETE http://localhost:8080/RESTfulApp/rest/user/id/12345
 - RESTClient(a debugger for RESTful web services for verifying the APIs output)
     And very often to make sure that everything works correctly writing unit and integration tests. For that purposes let’s look to the next candidates:
 - REST-assured(Java DSL for easy testing a REST services)
 - Jersey Test Framework(allow to run tests on different lightweight containers, like Embedded glassfish, grizzly web server and lightweight HTTP server)
     Let's try to increase the quality and productivity of the application using Jersey Test Framework.
     First we are adding necessary dependencies to the pom.xml file:
  <dependencies>
    .....
    <dependency>
      <groupId>com.sun.jersey.jersey-test-framework</groupId>
      <artifactId>jersey-test-framework-core</artifactId>
      <version>1.9</version>
      <scope>test</scope>
    </dependency>
    <dependency>
      <groupId>com.sun.jersey.jersey-test-framework</groupId>
      <artifactId>jersey-test-framework-external</artifactId>
      <version>1.9</version>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.11</version>
      <scope>test</scope>
    </dependency>
    .....
  </dependencies>
     Well, our UserServiceTest extends JerseyTest class and override the configure() method, where you supply the same information that you provide in web.xml file. WebResources is defined an encapsulation of a Web resource capable of building requests to send to the Web resource and processing responses returned from the Web resource.
/**
 * Integration test for UserService service.
 * 
 * @author Dmitry Nikolaenko
 *
 */
public class UserServiceTest extends JerseyTest {
    private final WebResource webResource = client().resource("http://localhost:8080/RESTfulApp/rest");

    @Override
    protected AppDescriptor configure() {
        return new WebAppDescriptor.Builder().build();
    }
    
    @Test
    public void testGetStub() {
        String result = webResource.path("/user/stub").get(String.class);
        Assert.assertEquals("stub", result);
    }
    
    @Test
    public void testCreateUser() throws JSONException {
        final User testUser = new User("123", "Tom", "Jenkins", "tom.jenkins@gmail.com");
        final ClientResponse response = webResource.path("/user/create").
                type(MediaType.APPLICATION_JSON).
                accept(MediaType.APPLICATION_JSON).
                post(ClientResponse.class, testUser);
        final User user = response.getEntity(new GenericType<User>(){});
        
        Assert.assertEquals("123", user.getId());
        Assert.assertEquals("Tom", user.getFirstName());
        Assert.assertEquals("Jenkins", user.getLastName());
        Assert.assertEquals("tom.jenkins@gmail.com", user.getEmail());
        // check HTTP status code
        Assert.assertEquals(200, response.getStatus());
    }
    
    @Test
    public void testDeleteUser() {
        final ClientResponse response = webResource.path("/user/id/12345").
                type(MediaType.APPLICATION_JSON).delete(ClientResponse.class);
        Assert.assertEquals(200, response.getStatus());
    }
    
    @Test
    public void testUpdateUser() {
        User testUser = new User("12345", "Tom", "Jenkins", "tom.jenkins@gmail.com");
        final ClientResponse response = webResource.path("/user/id/12345").
                type(MediaType.APPLICATION_JSON).
                accept(MediaType.APPLICATION_JSON).
                put(ClientResponse.class, testUser);
        final User user = response.getEntity(new GenericType<User>(){});
        
        Assert.assertEquals("12345", user.getId());
        Assert.assertEquals("Tom", user.getFirstName());
        Assert.assertEquals("Jenkins", user.getLastName());
        Assert.assertEquals("tom.jenkins@gmail.com", user.getEmail());
    }
    
    @Test
    public void testGetAllUsers1() throws JSONException {
        final ClientResponse response = webResource.path("/user/all").
                accept(MediaType.APPLICATION_JSON).get(ClientResponse.class);
        final JSONArray resultArray = response.getEntity(JSONArray.class);
        Assert.assertEquals(200, response.getStatus());
    }
    
    /**
     * Jersey using JAXB for the marshalling/unmarshalling process, 
     * and JAXB JSON processor is not standard.
     * So, I chose Jackson instead of JAXB.
     * 
     * @throws JSONException
     */
    @Test
    public void testGetAllUsers2() throws JSONException {
        ClientConfig clientConfig = new DefaultClientConfig();
        clientConfig.getClasses().add(JacksonJsonProvider.class);
        Client client = Client.create(clientConfig);
        final List<User> result = client.resource("http://localhost:8080/RESTfulApp/rest/user/all").
                get(new GenericType<List<User>>(){});
        
        final User user = result.get(0);
        Assert.assertEquals("1", user.getId());
        Assert.assertEquals("Tom", user.getFirstName());
        Assert.assertEquals("Jenkins", user.getLastName());
        Assert.assertEquals("tom.jenkins@gmail.com", user.getEmail());
        Assert.assertFalse(result.isEmpty());
    }
    
    @Test
    public void testGetUserById1() throws JSONException {
        JSONObject json = webResource.path("/user/id/12345").get(JSONObject.class);
        Assert.assertEquals("12345", json.get("id"));
        Assert.assertEquals("Max", json.get("firstName"));
        Assert.assertEquals("Liano", json.get("lastName"));
        Assert.assertEquals("maxliano@gmail.com", json.get("email"));
    }
    
    @Test
    public void testGetUserById2() throws JSONException {
        final ClientResponse response = webResource.path("/user/id/12345").
                accept(MediaType.APPLICATION_JSON).get(ClientResponse.class);
        // GenericType<Type> restore and map into User.java class
        final User user = response.getEntity(new GenericType<User>(){});
        
        Assert.assertEquals("12345", user.getId());
        Assert.assertEquals("Max", user.getFirstName());
        Assert.assertEquals("Liano", user.getLastName());
        Assert.assertEquals("maxliano@gmail.com", user.getEmail());
        // check HTTP status code
        Assert.assertEquals(200, response.getStatus());
    }
}
     The result of the tests will be displayed in the JUnit view and as we see we get a green bar.
    The complete source code to this example is available on Github. Have fun with the code!

Комментариев нет:

Отправить комментарий