Last week in Norcross, GA we were creating a RESTful application in Spring 3.2. We injected a service to the RESTful controller. The Service talked to the database using a DAO.
One weird thing I noticed when the guys were coding was, after implementing the DAO they ran the code in the browser every time to test the methods in the DAO class. It’s not only frustrating but also time consuming to be testing your DAO operations by bringing up your controller in the browser.
The best way to handle this is throw in an unit test while you code the DAO class. So by the time you’re writing the controller DAO is all set and working fine. Here’s a DAO class called TopicDao and a corresponding TopicDaoTest class. The TopicDao uses a POJO Topic.
//Topic.java public class Topic { private int id; private String title; private int duration; public int getId() { return id; } public void setId(int id) { this.id = id; } public String getTitle() { return title; } public void setTitle(String title) { this.title = title; } public int getDuration() { return duration; } public void setDuration(int duration) { this.duration = duration; } public Topic(int id, String title, int duration) { this.id = id; this.title = title; this.duration = duration; } public Topic() { } }
//TopicDao.java @Repository public class TopicDao { private JdbcTemplate jdbcTemplate; @Autowired public void setJdbcTemplate(JdbcTemplate jdbcTemplate) { this.jdbcTemplate = jdbcTemplate; } public List<Topic> getAllTopics(){ List<Topic> topics = null; topics = jdbcTemplate.query("select * from topics", new RowMapper<Topic>(){ public Topic mapRow(ResultSet rs, int index) throws SQLException { Topic topic = new Topic(rs.getInt("id"),rs.getString("title"),rs.getInt("duration")); return topic; } }); return topics; } public Topic select(int id){ Topic topic = null; Map<String,Object> map = jdbcTemplate.queryForMap("select * from topics where id=?",id); if(map != null && map.size() == 3) topic = new Topic((Integer)map.get("id"),map.get("title").toString(),(Integer)map.get("duration")); return topic; } public int insert(String title,int duration){ return jdbcTemplate.update("insert into topics(title,duration) values(?,?)",title,duration); } }
@RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(locations="file:WebContent/WEB-INF/applicationContext.xml") public class TopicDaoTest { private TopicDao topicDao; private ApplicationContext applicationContext; @Before public void tearDown(){ JdbcTemplate jdbcTemplate = applicationContext.getBean("jdbcTemplate",JdbcTemplate.class); jdbcTemplate.update("delete from topics"); } @Autowired public void setApplicationContext(ApplicationContext applicationContext) { this.applicationContext = applicationContext; } @Autowired public void setTopicDao(TopicDao topicDao) { this.topicDao = topicDao; } @Test public void testTopicDaoNotNull() { assertTrue(topicDao != null); } @Test public void testLoadAllTopics() { JdbcTemplate jdbcTemplate = applicationContext.getBean("jdbcTemplate",JdbcTemplate.class); jdbcTemplate.update("insert into topics(title,duration) values(?,?)","Test1",30); jdbcTemplate.update("insert into topics(title,duration) values(?,?)","Test2",40); List<Topic> topics = topicDao.getAllTopics(); assertNotNull(topics.size() == 2); } @Test public void testLoadTopic() { JdbcTemplate jdbcTemplate = applicationContext.getBean("jdbcTemplate",JdbcTemplate.class); jdbcTemplate.update("insert into topics(title,duration) values(?,?)","Test1",30); int id = jdbcTemplate.queryForObject("select max(id) from topics",Integer.class); Topic topic = topicDao.select(id); assertNotNull(topic); } @Test public void testInsertTopic() { int num = topicDao.insert("Ruby", 50); assertTrue(num == 1); } }
You can notice the applicationContext.xml file injected using the @ContextConfiguration annotation. You can always create a separate test configuration file and configure a test database to run your tests.