Wednesday, August 12, 2009

Using Spring with multiple databases Part 5, Unit Testing using JUnit 4 and Annotations

One of the great features of the Spring framework is they have create support for Unit Testing in JUnit. Also you have the ability to use Annotations to cut down on the amount of xml you need to get your test code up and running.
Here is a example that I used to test my Login Controller:


package com.endurotracker.gwt.server.web.controllers;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;

import java.util.List;

import org.apache.log4j.Logger;
import org.junit.runner.RunWith;
import org.junit.Test;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.Authentication;
import org.springframework.security.context.SecurityContext;
import org.springframework.security.context.SecurityContextHolder;
import org.springframework.security.context.SecurityContextImpl;
import org.springframework.security.providers.UsernamePasswordAuthenticationToken;
import org.springframework.security.providers.dao.DaoAuthenticationProvider;
import org.springframework.security.providers.dao.cache.EhCacheBasedUserCache;
import org.springframework.security.userdetails.UserDetails;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.transaction.TransactionConfiguration;
import org.springframework.transaction.annotation.Transactional;

import com.endurotracker.gwt.dao.UsersDao;
import com.endurotracker.gwt.model.ServerSideUser;
import com.endurotracker.gwt.model.Users;
import com.endurotracker.gwt.server.service.UserService;

/**
* @author David
*
*/
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = { "/applicationContext.xml","/jndi.xml","/applicationContext-acegi-security.xml" })
@TransactionConfiguration(transactionManager="jtaTransactionManager", defaultRollback=false)
@Transactional
public class LoginControllerTest {

@Autowired
private DaoAuthenticationProvider daoAuthenticationProvider;
@Autowired
private UsersDao userDetailsService;
@Autowired
private UsersDao usersDao;
@Autowired
private EhCacheBasedUserCache userCache;

@Autowired
private UserService userService;
@Autowired
LoginController loginController;

private static final Logger log = Logger.getLogger(LoginControllerTest.class);



@Test
public void testLogin()
{
UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken("admin","pwd");

Authentication auth = daoAuthenticationProvider.authenticate(token);

//set SecurityContext
SecurityContext context = new SecurityContextImpl();
context.setAuthentication(auth);
SecurityContextHolder.setContext(context);

Object obj = auth.getPrincipal();
String username = "";

if (obj instanceof UserDetails) {
username = ((UserDetails) obj).getUsername();
} else {
username = obj.toString();
}

//place in Cache
log.debug("loadUserByUsername " + username);

ServerSideUser serverUser = null;

boolean useCache = true;

if (useCache) {
serverUser = (ServerSideUser) userCache
.getUserFromCache(username);
}

List users;
Users u;
if (serverUser == null) {

users = usersDao.GetByProperty("username", username);
if(users.size() > 0)
{
u = users.get(0);
userCache.putUserInCache(new ServerSideUser(u));
}
else
{
u = null;
}

}

//Test if user can now be found, after being placed in cache
Users user = userService.getCurrentUser();

loginController = new LoginController(user);

assertNotNull(loginController);



}

@Test
public void testShowLogin()
{
loginController = new LoginController();
String returnViewname = loginController.showHandler();

assertEquals("showLogin",returnViewname);
}
}



Hopefully, these posts will help some people who had very little success previously finding good examples on how to setup Spring with multiple databases (datasources).
I know I did.

1 comment:

  1. I think Spring can't help you here. Spring provides nice and clean transaction handling of Hibernate's Session, DAO and template exposure, but as far as object graph loading is concerned, it all depends on Hibernate API. I had similar request. I then wrote a small persistant library. Now I would look for different solution - maybe ' front-ending the databases with third party software'.

    ginko

    ReplyDelete