четверг, 26 сентября 2013 г.

Integration and unit testing with JUnit and Spring Framework

     Testing is the important part of software development. But very often it turns to some kind of challenge. In this article we will use Spring Framework because it provide excellent support for integration and unit testing. 
     Unit testing is used to test a some unit or module in the application in isolation, but integration testing of the application also very important. They help to see different behavior when integrated with other modules in the application. 
     Continuing the previous article, here I’ll show a way to test a service layer with Spring, JUnit, HSQLDB and Maven. First of all, let’s remember the necessary configuration files. Here they are: spring-beans-test.xml, servlet-context-test.xml, persistence-test.xml, all these files are in the src/test/resources package. The description for each file can be found in my previous post. 
     Now we’re ready to write a unit test that will check all the methods of the UserService service.
     Well, a few lines of code speaks more than a thousand words from me...
/**
 * Unit test for the client service layer.
 * 
 * @author Dmitry Nikolaenko
 *
 */
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = { 
        "/spring-beans-test.xml", 
        "/servlet-context-test.xml" })
public class UserServiceTest {
    @Autowired
    private UserService userService;
    
    @Test
    public void createTest() {
        User user = userService.create(createTestUser());
        
        Assert.assertNotNull(user);
        Assert.assertNotNull(user.getId());
        Assert.assertEquals("Tom", user.getName());
    }
    
    @Test
    public void deleteTest() {
        User user = userService.create(createTestUser());
        userService.delete(user.getId());
        User deletedUser = userService.find(user.getId());
        
        Assert.assertNull(deletedUser);
    }
    
    @Test
    public void updateTest() {
        User user = userService.create(createTestUser());
        user.setName("Bob");
        userService.update(user);
        User foundUser = userService.find(user.getId());
        
        Assert.assertNotNull(foundUser);
        Assert.assertEquals("Bob", foundUser.getName());
    }
    
    @Test
    public void findTest() {
        User user = userService.create(createTestUser());
        User foundUser = userService.find(user.getId());
        
        Assert.assertNotNull(foundUser);
        Assert.assertNotNull(foundUser.getId());
        Assert.assertEquals("Tom", foundUser.getName());
    }
    
    @Test
    public void getAllTest() {
        userService.create(createTestUser());
        List<User> users = userService.getAll();
        
        Assert.assertNotNull(users);
        Assert.assertFalse(users.isEmpty());
    }
    
    @Test
    public void countTest() {
        userService.create(createTestUser());
        long before = userService.count();
        userService.create(createTestUser());
        long after = userService.count();
        
        Assert.assertEquals(before, after - 1);
    }
    
    /**
     * Create a test user.
     */
    private User createTestUser() {
        User user = new User();
        user.setAge(30);
        user.setName("Tom");
        
        return user;
    }
}
     UserServiceTest annotated as @RunWith(SpringJUnit4ClassRunner.class). Class provides functionality of the Spring TestContext Framework to standard JUnit. It means that Spring JUnit runner allows you to set up Spring ApplicationContext for tests and use dependency injection. 
     @ContextConfiguration(locations = { "/spring-beans-test.xml", "/servlet-context-test.xml" }) tells the path where is located application context to load for test
     @Autowired allow autowired by Spring's dependency injection facilities.
     The source code of our integration test looks as follows.
/**
 * Integration test.
 * 
 * @author Dmitry Nikolaenko
 *
 */
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = { 
        "/spring-beans-test.xml", 
        "/servlet-context-test.xml" })
public class UserRestServiceTest {
    private static final String REST_APP_URL = "http://localhost:8080/RESTfulWebApp/rest/users";
    private RestTemplate restTemplate = new RestTemplate();
            
    @Test
    public void addUserTest() {
        // create a new resource by POSTing the given object to the URI template, 
        // and returns the representation found in the response. 
        User createdUser = restTemplate.postForObject(REST_APP_URL, createUser(), User.class);
        
        Assert.assertNotNull(createdUser);
        Assert.assertEquals("Tom", createdUser.getName());
        Assert.assertNotNull(createdUser.getId());
    }
    
    @Test
    public void findUserTest() {
        User createdUser = restTemplate.postForObject(REST_APP_URL, createUser(), User.class);
        
        // retrieve a representation by doing a GET on the specified URL, 
        // the response is converted and returned. 
        User userFound = restTemplate.getForObject(createRestAppUrl(createdUser), User.class);
        Assert.assertNotNull(userFound);
        Assert.assertEquals("Tom", userFound.getName());
        Assert.assertNotNull(userFound.getId());
    }
    
    @Test
    public void updateUserTest() {
        User createdUser = restTemplate.postForObject(REST_APP_URL, createUser(), User.class);
        
        createdUser.setName("Bob");
        // update a resource by PUTing the given user to the URI
        restTemplate.put(createRestAppUrl(createdUser), createdUser);
        User userFound = restTemplate.getForObject(createRestAppUrl(createdUser), User.class);
        
        Assert.assertNotNull(userFound);
        Assert.assertEquals("Bob", userFound.getName());
    }
    
    @Test
    public void loadUsersTest() {
        restTemplate.postForObject(REST_APP_URL, createUser(), User.class);
        Users users = (Users) restTemplate.getForObject(REST_APP_URL, Users.class);
        
        Assert.assertNotNull(users);
        Assert.assertNotNull(users.getUsers());
        Assert.assertFalse(users.getUsers().isEmpty());
    }
    
    @Test
    public void deleteUserTest() {
        // just create new user
        User createdUser = restTemplate.postForObject(REST_APP_URL, createUser(), User.class);
        
        // testing...
        Assert.assertNotNull(createdUser);
        Assert.assertEquals("Tom", createdUser.getName());
        Assert.assertNotNull(createdUser.getId());
        
        // try to find it and then testing...
        User userFound = restTemplate.getForObject(createRestAppUrl(createdUser), User.class);
        Assert.assertNotNull(userFound);
        Assert.assertEquals("Tom", userFound.getName());
        Assert.assertNotNull(userFound.getId());
        
        // delele it
        restTemplate.delete(createRestAppUrl(userFound));
        
        // and finally try to find again, but we lost him forever
        User deletedUser = restTemplate.getForObject(createRestAppUrl(createdUser), User.class);
        Assert.assertNull(deletedUser);
    }
    
    /**
     * Create a test user.
     */
    private User createUser() {
        User user = new User();
        user.setAge(30);
        user.setName("Tom");
        
        return user;
    }
    
    /**
     * Construct REST URL for testing.
     * 
     * @param user for testing
     */
    private String createRestAppUrl(User user) {
        return REST_APP_URL.concat("/").concat(user.getId().toString());
    }
}
     Now you can test functionality with Curl.
http://localhost:8080/RESTfulWebApp/rest/users - get all users (GET) http://localhost:8080/RESTfulWebApp/rest/users - create user (POST) http://localhost:8080/RESTfulWebApp/rest/users/5 - find user by id = 5 (GET) http://localhost:8080/RESTfulWebApp/rest/users/5 - update user with id = 5 (PUT) http://localhost:8080/RESTfulWebApp/rest/users/5 - delete user with id = 5 (DELETE)
     Source code of the project available on Github.

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

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