0

我有单元测试来测试休眠过程让我通过这个

下面是我的 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,它变成了 null!

这怎么可能发生?需要一些解释,我该如何解决这个问题?

4

1 回答 1

0

使用真实对象进行测试确实是一种不好的做法,除非这些测试是集成测试。你有为此目的的模拟对象:jmockEasyMockMockito是你会找到的最好的 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);
}
于 2012-08-28T10:23:58.857 回答