Page 1 of 2 12 LastLast
Results 1 to 10 of 13

Thread: Clearing the context to avoid out of memory when using JUnit test

  1. #1

    Default Clearing the context to avoid out of memory when using JUnit test

    I use JUnit tests from within Eclipse to test my code. My problem is that each test sets up a new applicationContext and don't seem to be able to get rid of it by just nulling the reference. So I quickly get a heck of a lot of instances of objects and I run out of memory. (Everything becomes REALLY slow) Is there a clever way to get rid of all Spring objects from memory when I am done with a test and goes on to the next one?

    // Jonathan

  2. #2
    Join Date
    Jun 2006
    Location
    The Netherlands
    Posts
    13,625

    Default

    Are you using your own test mechanism or use the test classes provided by Spring? I strongly suggest you use the latter.
    Marten Deinum
    Java Consultant / Pragmatist / Open Source Enthousiast / Author


    Pro Spring MVC: With Web Flow
    Conspect

    Have you read the reference guide.
    Use the [ code ] tags, young padawan

  3. #3

    Default

    Quote Originally Posted by mdeinum View Post
    Are you using your own test mechanism or use the test classes provided by Spring? I strongly suggest you use the latter.
    Are there test classes provided by Spring? Will they help with this? my tests looks a little bit like this:

    Code:
    package net.bioclipse.lis.tests.daos;
    
    import java.util.ArrayList;
    import java.util.List;
    
    import org.junit.Test;
    
    import static org.junit.Assert.*;
    
    import net.bioclipse.lis.genericDAO.IUserDAO;
    import net.bioclipse.lis.pojos.User;
    
    /**
     * Tests all the functionality of the <code>UserDAO</code>
     * 
     * @author jonathan
     *
     */
    public class UserDAOTest extends AbstractGenericDAOTest {
    	
    	public IUserDAO getDAO(){
    		return (IUserDAO)dao;
    	}
    	
    	public UserDAOTest() {
    		super("userDAO");
    	}
    
    	/**
    	 * Test method for {@link net.bioclipse.lis.daos.UserDAO#delete(long)}.
    	 */
    	@Test
    	public void testDelete() {
    		User user   = User.createUser("Delete Tester");
    		assertFalse(user.isDeleted());
    		getDAO().save(user);
    		
    		session.flush();
    		session.clear();
    		
    		getDAO().delete(user.getId());
    		
    		session.flush();
    		session.clear();
    		
    		User deleted = getDAO().getById(new Long(user.getId()));
    		assertTrue(deleted.isDeleted());
    	}
    
    	/**
    	 * Test method for {@link net.bioclipse.lis.daos.UserDAO#getAll()}.
    	 */
    	@Test
    	public void testGetAll() {
    		
    		User user1 = User.createUser("Getall Tester1");
    		User user2 = User.createUser("Getall Tester2");
    		getDAO().save(user1);
    		getDAO().save(user2);
    		
    		session.flush();
    		session.clear();
    		
    		List list = getDAO().findAll();
    		assertTrue(list.contains(user1));
    		assertTrue(list.contains(user2));
    	}
    
    	
    	/**
    	 * Test method for {@link net.bioclipse.lis.daos.UserDAO#save(net.bioclipse.lis.pojos.User)}.
    	 */
    	@Test
    	public void testSave() {
    		User user = User.createUser("Save Tester");
    		getDAO().save(user);
    		
    		session.flush();
    		session.clear();
    		
    		User savedUser = getDAO().getById(user.getId());
    		assertEquals(user, savedUser);
    		assertNotSame(user, savedUser);
    	}
    	
    	/**
    	 * Test method for {@link net.bioclipse.lis.daos.UserDAO#getById(long)}.
    	 */
    	@Test
    	public void testGetById() {
    		User user = User.createUser("Getbyid Tester");
    		getDAO().save(user);
    		
    		session.flush();
    		session.clear();
    		
    		User savedUser = getDAO().getById(new Long(user.getId()));
    		assertEquals(user, savedUser);
    		assertNotSame(user, savedUser);		
    	}
    	
    	@Test
    	public void testFindByName() {
    		User user = User.createUser("findMe");
    		getDAO().save(user);
    		
    		session.flush();
    		session.clear();
    		
    		ArrayList<User> retrievedUsers = (ArrayList<User>)getDAO().findByName("findMe");
    		User savedUser = retrievedUsers.get(0);
    		assertEquals(user, savedUser);
    		assertNotSame(user, savedUser);	
    	}
    }
    Code:
    public abstract class AbstractGenericDAOTest {
    
    	protected IGenericDAO dao;
    	protected Session     session;
    	protected ApplicationContext context;
    //snip
    public AbstractGenericDAOTest(String DAOBeanName){
    		context = new ClassPathXmlApplicationContext("applicationContext.xml");		
    		dao = (IGenericDAO)context.getBean(DAOBeanName);
    		session = SessionFactoryUtils.getSession(dao.getSessionFactory(),true);
    		
    	}
    
    @Before
    	public void setUp() throws Exception {
    
    		net.bioclipse.lis.tests.Tools.newCleanDatabase();
    		TransactionSynchronizationManager.bindResource(dao.getSessionFactory(), new SessionHolder(session));
    
    //snipp
    
    @After
    	public void tearDown(){
    		
    		TransactionSynchronizationManager.unbindResource(dao.getSessionFactory());
    		SessionFactoryUtils.releaseSession(session, dao.getSessionFactory());
    And they works fine except for when I run alot of them at the same time...

  4. #4
    Join Date
    Jun 2006
    Location
    The Netherlands
    Posts
    13,625

    Default

    Spring provides test classes for well everything you did on your own. The Spring test classes will also inject dependencies in your testclass! Also it will only load the applicationcontext once instead of before every test method, it also takes care of transaction management for you, instead of doing it yourself.

    Read chapter 8 of the reference guide, which covers testing. You also might want to checkout the [url=http://www.springframework.org/docs/api/org/springframework/test/AbstractSpringContextTests.html]javadocs[url] regarding the test classes.

    The rewrite in your case would be

    Code:
    public abstract class AbstractGenericDAOTest extends org.springframework.test.AbstractTransactionalSpringContextTests{
    
      private static final String[] LOCATIONS = {"applicationContext.xml"}
    
      public AbstractGenericDAOTest() {
        setAutowireMode(AUTOWIRE_BY_NAME);
      }
    
      protected String[] getConfigLocations() {
        return LOCATIONS;
      }
    }
    
    package net.bioclipse.lis.tests.daos;
    
    import java.util.ArrayList;
    import java.util.List;
    
    import org.junit.Test;
    
    import static org.junit.Assert.*;
    
    import net.bioclipse.lis.genericDAO.IUserDAO;
    import net.bioclipse.lis.pojos.User;
    
    /**
     * Tests all the functionality of the <code>UserDAO</code>
     * 
     * @author jonathan
     *
     */
    public class UserDAOTest extends AbstractGenericDAOTest {
    	
    	private GenericDao dao;
    	
    	//Spring will inject this for you.
    	public void setIUserDao(GenericDao dao){
    		return this.dao=dao;
    	}
    	
    	public UserDAOTest() {
    		super();
    	}
    
    	/**
    	 * Test method for {@link net.bioclipse.lis.daos.UserDAO#delete(long)}.
    	 */
    	@Test
    	public void testDelete() {
    		User user   = User.createUser("Delete Tester");
    		assertFalse(user.isDeleted());
    		dao.save(user);
            setComplete()
            endTransaction();
            startTransaction();		
    		
    		dao.delete(user.getId());
    		
            setComplete()
            endTransaction();
            startTransaction();		
    		
    		User deleted = dao.getById(new Long(user.getId()));
    		assertTrue(deleted.isDeleted());
    	}
    
    	/**
    	 * Test method for {@link net.bioclipse.lis.daos.UserDAO#getAll()}.
    	 */
    	@Test
    	public void testGetAll() {
    		
    		User user1 = User.createUser("Getall Tester1");
    		User user2 = User.createUser("Getall Tester2");
    		dao.save(user1);
    		dao.save(user2);
            setComplete()		
            endTransaction();
            startTransaction();		
    		
    		List list = dao.findAll();
    		assertTrue(list.contains(user1));
    		assertTrue(list.contains(user2));
    	}
    
    	
    	/**
    	 * Test method for {@link net.bioclipse.lis.daos.UserDAO#save(net.bioclipse.lis.pojos.User)}.
    	 */
    	@Test
    	public void testSave() {
    		User user = User.createUser("Save Tester");
    		dao.save(user);
    	        setComplete()	
            endTransaction();
            startTransaction();		
    		
    		User savedUser = dao.getById(user.getId());
    		assertEquals(user, savedUser);
    		assertNotSame(user, savedUser);
    	}
    	
    	/**
    	 * Test method for {@link net.bioclipse.lis.daos.UserDAO#getById(long)}.
    	 */
    	@Test
    	public void testGetById() {
    		User user = User.createUser("Getbyid Tester");
    		dao.save(user);
    	        setComplete()	
            endTransaction();
            startTransaction();		
    		
    		User savedUser = dao.getById(new Long(user.getId()));
    		assertEquals(user, savedUser);
    		assertNotSame(user, savedUser);		
    	}
    	
    	@Test
    	public void testFindByName() {
    		User user = User.createUser("findMe");
    		dao.save(user);
    	        setComplete()	
            endTransaction();
            startTransaction();		
    		
    		ArrayList<User> retrievedUsers = (ArrayList<User>)dao.findByName("findMe");
    		User savedUser = retrievedUsers.get(0);
    		assertEquals(user, savedUser);
    		assertNotSame(user, savedUser);	
    	}
    }
    Last edited by Marten Deinum; Jul 3rd, 2007 at 08:09 AM.
    Marten Deinum
    Java Consultant / Pragmatist / Open Source Enthousiast / Author


    Pro Spring MVC: With Web Flow
    Conspect

    Have you read the reference guide.
    Use the [ code ] tags, young padawan

  5. #5

    Default

    Thanks I'll have to test that and see if it solves my problems

    // Jonathan

  6. #6
    Join Date
    Jun 2006
    Location
    The Netherlands
    Posts
    13,625

    Default

    Your welcome, I give no garantues as I simply typed it in the edit box . Hmm I wonder is knowing the Spring API from the top of your head bad?!
    Marten Deinum
    Java Consultant / Pragmatist / Open Source Enthousiast / Author


    Pro Spring MVC: With Web Flow
    Conspect

    Have you read the reference guide.
    Use the [ code ] tags, young padawan

  7. #7
    Join Date
    Aug 2006
    Location
    Now Germany, previously Ukraine
    Posts
    1,546

    Default

    Quote Originally Posted by Jonathan Alvarsson View Post
    Thanks I'll have to test that and see if it solves my problems

    // Jonathan
    There is one small issue - Spring test classes are JUnit 3.8.1 based and you have strived to use JUnit 4.x. If using of Junit 4 is important for you, then start not from using Spring test classes, but just by converting application context in your tests into the static field. It should be enough to solve your problem.

    BTW, I vaguely remember that some project exists for porting Spring test classes to JUnit4, but I do not remeber details. Try to search this forum, it was discussed here some time ago.

  8. #8
    Join Date
    Jun 2006
    Location
    The Netherlands
    Posts
    13,625

    Default

    Oops, missed that bit .

    Spring 2.1 provides JUnit 4 integration. However the lack of integration support for JUnit and/or TestNG led us to unitils. Next to that it also provides DBUnit integration and some other convenience tools.
    Marten Deinum
    Java Consultant / Pragmatist / Open Source Enthousiast / Author


    Pro Spring MVC: With Web Flow
    Conspect

    Have you read the reference guide.
    Use the [ code ] tags, young padawan

  9. #9

    Default

    //Spring will inject this for you.
    public void setIUserDao(GenericDao dao){
    return this.dao=dao;
    }
    Based upon what can Spring make this sort of injection? There is not any xml definitions to work by...

    I need something like this:
    Code:
            <bean id="userDAO" parent="abstractDAO">
            <property name="proxyInterfaces">
            	<value>net.bioclipse.lis.genericDAO.IUserDAO</value>
        	</property>
        	<property name="target">
            	<bean parent="abstractDAOTarget">
                	<constructor-arg>
                    	<value>net.bioclipse.lis.pojos.User</value>
                	</constructor-arg>
            	</bean>
        	</property>
    	</bean>
    See: <http://www.ibm.com/developerworks/java/library/j-genericdao.html>

  10. #10
    Join Date
    Aug 2006
    Location
    Now Germany, previously Ukraine
    Posts
    1,546

    Default

    Quote Originally Posted by mdeinum View Post
    Oops, missed that bit .

    Spring 2.1 provides JUnit 4 integration. However the lack of integration support for JUnit and/or TestNG led us to unitils. Next to that it also provides DBUnit integration and some other convenience tools.
    Spring 2.1 is not yet here (it even not reached RC stage).
    And my first impression of unutils was not that good, but I have not used them, just have taken a look.

    Really, I'm happy with JUnit 3.8.1 and do not see (for me) any real need in the migration to JUnit 4 or TestNG.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •