Pages

Categories

Enumerations and jMock… ouch! But here’s how.

I may write an article on jMock eventually but right now I’m just dropping by to throw this home-brewed code onto the web to help out a few Java developers who have hit hurdles using jMock and returning Enumeration instances from a stub/mock method.

jMock provides only 3 different actions for returning values by default. There’s ReturnvalueAction which returns a reference to the object you give it, ReturnDefaultValueAction which returns a basic default matching the required type and ReturnIteratorAction which returns re-usable Iterator instances. ReturnIteratorAction was created to tackle a very similar problem.

When you use ReturnValueAction (or the returnValue() method of org.jmock.Expectations) you simply get a reference to your object. This means that for Iterators and Enumerations, once they’ve been iterated over they’re completely exhausted, or if you partially iterate over one your remaining tests will provide unpredictable results.

The objective here is to provide a cloned Enumeration every time you invoke the mocked method. Here’s how I did it:

(Apologies for the syntax highlighting. Not sure what GeSHi is doing with it).

/*
 Provides a way to return Enumeration objects from a Mock object.
 This gets around the problem with Enumerations being exhausted using
 org.jmock.lib.actions.ReturnValueAction.
 
 This program is free software: you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
 the Free Software Foundation, either version 3 of the License, or
 (at your option) any later version.
 
 This program is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details.

 You should have received a copy of the GNU General Public License
 along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
 */

package org.mayo.jmock;

import org.hamcrest.Description;
import org.jmock.api.Action;
import org.jmock.api.Invocation;
import java.util.Set;
import java.util.HashSet;
import java.util.Enumeration;
import java.util.Iterator;

/**
 * Allows Enumeration to be returned from a Mock object with the jMock framework.
 * A new Enumeration will be returned for each invokation of the mock method.
 * @author Chris Corbyn <chris@w3style.co.uk>
 */

public class ReturnEnumerationAction<E> implements Action {
 
  /** The values from the Enumeration as a Set */
  private Set<E> set;
 
  /**
   * Constructs a new Action using the given Enumeration.
   * The Enumeration will be exhasuted initially, but invoking
   * ReturnEnumerationAction.invoke() will return a clone of it.
   * @param Enumeration<E> target
   */

  public ReturnEnumerationAction(Enumeration<E> target) {
    set = new HashSet<E>();
    while (target.hasMoreElements()) {
      set.add(target.nextElement());
    }
  }
 
  /**
   * Invoke this Action to get a new Enumeration like the original.
   * @param Invocation invocation
   * @return Enumeration<E>
   * @throws Throwable
   */

  public Enumeration<E> invoke(Invocation invocation) throws Throwable {
    final Set<E> set = this.set;
    return new Enumeration<E>() {
      Iterator<E> it = set.iterator();
      public boolean hasMoreElements() {
        return it.hasNext();
      }
      public E nextElement() {
        return it.next();
      }
    };
  }
 
  /**
   * Describe this action.
   * This is not implemented, mostly because I’m too lazy to find out how.
   * @param Description description
   */

  public void describeTo(Description description) {
  }
 
}

You use it like this:

mockery.checking(new Expectations() {{
  one(mockObject).mockMethod();
      will(new ReturnEnumerationAction(yourEnum));
}});

Hopefully this helps a few people :) I had googled for a solution before writing this and didn’t see any code despite several queries about it.

This entry was posted on Saturday, September 15th, 2007 at 11:47 am and is filed under Java. You can follow any responses to this entry through the RSS 2.0 feed. You can leave a response, or trackback from your own site.

2 Responses to “Enumerations and jMock… ouch! But here’s how.”

  • Nat [ 01Dec07]

    A returnEnumeration action will be in the next version of jMock.

  • chris [ 01Dec07]

    Excellent. I saw the commit to the repository and I have to say the solution you used looks far more elegant :)

Leave a Reply







XHTML: You can use these tags: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <code> <em> <i> <strike> <strong>