The Artima Developer Community
Sponsored Link

Java Buzz Forum
Mock around the Clock

0 replies on 1 page.

Welcome Guest
  Sign In

Go back to the topic listing  Back to Topic List Click to reply to this topic  Reply to this Topic Click to search messages in this forum  Search Forum Click for a threaded view of the topic  Threaded View   
Previous Topic   Next Topic
Flat View: This topic has 0 replies on 1 page
Zohar Melamed

Posts: 28
Nickname: zohar
Registered: Aug, 2003

Zohar Melamed is a Corporate Eejit
Mock around the Clock Posted: Aug 18, 2003 2:06 PM
Reply to this message Reply

This post originated from an RSS feed registered with Java Buzz by Zohar Melamed.
Original Post: Mock around the Clock
Feed Title: corporate eejit
Feed URL: http://sedoparking.com/search/registrar.php?domain=®istrar=sedopark
Feed Description: Insanity is Normal
Latest Java Buzz Posts
Latest Java Buzz Posts by Zohar Melamed
Latest Posts From corporate eejit

Advertisement


This came out of some testing I did with a project at work.

We have the following :


    /**
     *  given  a map of expression objects perform a lookup
     * @param searchExpressions a map of SearchExpression keyed on field name

     * @return
     */
    public Collection lookup(Class classToSearchFor, Map searchExpressions) throws SearchException {

        Session session = null;
        try {
            session = sessionFactory.openSession();
            Criteria criteria = session.createCriteria(classToSearchFor);
            Set fieldNames = searchExpressions.keySet();
            for (Iterator iterator = fieldNames.iterator(); iterator.hasNext();) {

                String fieldName = (String) iterator.next();
                SearchExperssion sexpr = (SearchExperssion) searchExpressions.get(fieldName);
                criteria.add(getHibernateExpression(sexpr));
            }

return criteria.list(); } catch (HibernateException e) { // todo add the details of the map throw new SearchException("Failed to run search for class = " + classToSearchFor.getName(), e); } finally { if (session != null) { try { session.close(); } catch (HibernateException e) { log.error(e.getMessage(), e); } } } }

The above function uses Hibernate's query by criteria facility to perform generic lookup for instances of any class mapped to the database using Hibernate.

The hibernate SessionFactory is passed in as a parameter to the ctor of this class. (This class will be a pico component)

There are 2 calls into hibernate in this function that can throw a checked exception (HibernateException in both cases).

  • SessionFactory.openSession
  • Criteria.list

We wanted to test in both cases that :

  • If created the session is closed when an exception is thrown ( no resource leaks )
  • If a Hibernate exception is thrown, the function throws a SearchException including the nested hibernate exception in the cause field
  • The message in the above exception is as we expect : Failed to run search for class = name of class we pass in.

Getting the latest version of MockObejcts, and using the DynaMock facility we can do the following :

The first test will cause the openSession call to fail with a hibernate exception. As we have not created a session there is no need to test for close being called.

We only verify that we get a SearchException and that it contains all we expect.



 public void testHibernateExceptionTranslatedToSearchException() throws SearchException {
        // create a dynamically mocked session factory  
        Mock mockSf = new Mock(SessionFactory.class);

HibernateException hibernateException = new HibernateException("a hibernate execption"); // the code below instructs the dynamock to throw the provided exception // when the "openSession" function is called mockSf.expectAndThrow("openSession",hibernateException);

SearchManager mySm = new SearchManager((SessionFactory) mockSf.proxy());

try { mySm.lookup(SearchConstants.MULTI_CPTY.searachFor, SearchConstants.MULTI_CPTY.searcahParameters); fail("should have thrown a searchexception"); } catch (SearchException e) {

assertSame("we expect our mock hibernate exception to be nested"+ "in this search exception",e.getCause(),hibernateException);

assertEquals("checking for the right message",e.getMessage(), "Failed to run search for class = " + SearchConstants.MULTI_CPTY.searachFor.getName()); }

}

The second test will delay the failure until the list method of the Criteria is called. By that stage we have an open session so we check both the correctness of the exception, and close being called on the open session. Additionally we check :

  • openSession is called
  • createCriteria is called with the corrrect argument
  • add is called on criteria passing in only instances of the hibernate Expression class( tested using the FullConstraintMatcher )


    /**
     * check that the (mock) hibernate session is being closed when we throw an exception
     * additionally test that if Criteria.list() throws an exception, it is dealt with in the same 
     * fashion as the 'other' checked exception in
     * the testHibernateExceptionTranslatedToSearchException
     *
     * @throws SearchException
     */
    public void testHibernateSessionisClosedAndGeneratedExceptionIsCorrect() throws SearchException {

Mock mockSf = new Mock(SessionFactory.class); HibernateException hibernateException = new HibernateException("a hibernate execption");

Mock mockSession = new Mock(Session.class);

mockSf.expectAndReturn("openSession", mockSession.proxy());

Mock mockCriteria = new Mock(Criteria.class);

mockCriteria.expectAndThrow("list", hibernateException);

// the call below tells the mock criteria to expect calls to add, // check that the argument passed in is an instance of Expression // and return a reference to itself ( ie. "return this;" )

mockCriteria.expectAndReturn("add", new FullConstraintMatcher(new IsInstanceOf(Expression.class)), mockCriteria.proxy());

mockSession.expectAndReturn("createCriteria", SearchConstants.MULTI_CPTY.searachFor, mockCriteria.proxy()); mockSession.expect("close");

SearchManager mySm = new SearchManager((SessionFactory) mockSf.proxy()); try {

mySm.lookup(SearchConstants.MULTI_CPTY.searachFor, SearchConstants.MULTI_CPTY.searcahParameters);

fail("should have thrown a search exception");

} catch (SearchException e) { assertSame("we expect our mock hibernate exception to be nested"+ "in this search exception", e.getCause(), hibernateException);

assertEquals("checking for the right message", e.getMessage(), "Failed to run search for class = " + SearchConstants.MULTI_CPTY.searachFor.getName()); }

mockSf.verify(); mockSession.verify(); mockCriteria.verify(); }



Simple and clean.

No need to write mock classes.

Less code written, more tested.

Read: Mock around the Clock

Topic: A Java bug worthy of your vote Previous Topic   Next Topic Topic: Book Corner: Eclipse Sightings

Sponsored Links



Google
  Web Artima.com   

Copyright © 1996-2019 Artima, Inc. All Rights Reserved. - Privacy Policy - Terms of Use