我有单元测试来测试hibernate过程让我通过这个
以下是我的AbstractDAO
public abstract class BaseDAO {
protected JdbcTemplate jdbcTemplate;
protected SessionFactory sessionFactory;
protected NamedParameterJdbcTemplate namedParameterJdbcTemplate;
...
@Autowired
public void setDataSource(DataSource dataSource) {
this.jdbcTemplate = new JdbcTemplate(dataSource);
this.namedParameterJdbcTemplate = new NamedParameterJdbcTemplate(dataSource);
}
@Autowired
public void setSessionFactory(SessionFactory sessionFactory) {
this.sessionFactory = sessionFactory;
}
}
这是我的concreteDAO,它扩展了BaseDAO
public class LoginDAO extends BaseDAO implements InitializingBean {
private static final Logger log = Logger.getLogger(LoginDAO.class);
private MD5PasswordEncoder passwordEncoder;
private SaltSource saltSource;
public User getLoggedinUserByUserid(Long userid){
log.info("in getLoggedinUserByUserid");
User result = null;
Session session = sessionFactory.openSession();
try {
session.beginTransaction();
result = (User) session.get(User.class, userid);
session.getTransaction().rollback();
session.close();
} catch (Exception e) {
log.error(e,e);
session.getTransaction().rollback();
session.close();
}
return result;
}
...
}
这是我的junit
@Test
public void shouldReturnCorrectlyUserWhenCallingGetLoggedinUserByUseridMethod() {
// Given When
User adminUser = loginDAO.getLoggedinUserByUserid(1l);
// Then
assertNotNull(adminUser);
assertEquals("sadmin", adminUser.getUsername());
assertEquals("ecedee8662a0bcd15c157e5734056ac5", adminUser.getPassword());
assertEquals(1, adminUser.getStatus());
assertEquals("TS", adminUser.getFirstname());
assertEquals("Sys Admin Person", adminUser.getLastname());
assertEquals(0, adminUser.getIdType());
assertTrue(adminUser.getEnabled());
assertTrue(adminUser.getAuthenLocal());
assertTrue(StringUtils.isBlank(adminUser.getTitle()));
}
SessionFactory在BaseDAO中被正确注入,但是当它出现时
Session session = sessionFactory.openSession();
中的LoginDAO
,它变为空!
怎么会发生这种情况?需要一些解释,如何解决这个问题?
答案 0 :(得分:0)
使用真实对象进行测试确实是一种不好的做法,除非这些测试是集成测试。您有用于此目的的模拟对象:jmock,EasyMock,Mockito是您将要搜索的最佳Java库。
也许您可以尝试使用类似OpenSessionInView的内容查找您的JPA或Hibernate Session,以查看MVC模式的View部分。它可能是这样的:
public abstract class AppContextTestCase extends TestCase {
protected FileSystemXmlApplicationContext context = null;
protected SessionFactory sessionFactory = null;
/* (non-Javadoc)
* @see junit.framework.TestCase#setUp()
*/
protected void setUp() throws Exception {
super.setUp();
String[] contextLocations = new String[2];
contextLocations[0] = "web/WEB-INF/applicationContext.xml";
contextLocations[1] = "test/dataSource-local.xml";
context = new FileSystemXmlApplicationContext(contextLocations);
sessionFactory = (SessionFactory) context.getBean("sessionFactory");
Session session = SessionFactoryUtils.getSession(sessionFactory, true);
TransactionSynchronizationManager.bindResource(sessionFactory, new SessionHolder(session));
}
/* (non-Javadoc)
* @see junit.framework.TestCase#tearDown()
*/
protected void tearDown() throws Exception {
SessionHolder sessionHolder = (SessionHolder) TransactionSynchronizationManager.unbindResource(sessionFactory);
SessionFactoryUtils.closeSessionIfNecessary(sessionHolder.getSession(), sessionFactory);
context = null;
super.tearDown();
}
}
或者做这样的事情:
protected void setUp() throws Exception {
Session session = SessionFactoryUtils.getSession(sessionFactory, true);
TransactionSynchronizationManager.bindResource(sessionFactory, new SessionHolder(session));
}
protected void tearDown() throws Exception {
SessionHolder sessionHolder = (SessionHolder) TransactionSynchronizationManager.unbindResource(sessionFactory);
SessionFactoryUtils.closeSessionIfNecessary(sessionHolder.getSession(), sessionFactory);
}