• Home
  • RSS Feed
  • Log in


Mocking Static Calls Revisited
Posted by Jeroen van Erp around lunchtime: June 22nd, 2007

Yesterday I presented you with a problem we were facing with mocking out the static call to FacesContext.getCurrentInstance(). The three solutions I presented all felt wrong somehow. Comments showed a fourth option, AOP. Today I will present you with yet another solution, which I think feels right in every way.

Somehow everything seems easier once you take a look at the code. I already knew that FacesContext was a ThreadLocal variable. But only today, once I saw the code, I realized what I was missing. Basically the abstract base class javax.faces.context.FacesContext looks like the following:

public abstract class FacesContext {
	private static ThreadLocal _currentInstance = new ThreadLocal();

	// Lot of abstract methods.

	public static FacesContext getCurrentInstance() {
		return (FacesContext)_currentInstance.get();
	}

	protected static void setCurrentInstance(FacesContext context) {
		_currentInstance.set(context);
	}
}

This means that when we implement our own version of a FacesContext, we can have it set itself in the ThreadLocal! The solution lies in a MockFacesContextWrapper class implemented as follows:

public class MockFacesContextWrapper extends FacesContext {
	private FacesContext mockContext;

	public MockFacesContextWrapper(FacesContext context) {
		this.mockContext = context;
		FacesContext.setCurrentInstance(this);
	}

	// Delegate methods for mockContext for all declared abstract methods in FacesContext
}

Now your tests can be implemented using a mocked FacesContext without having your source code being aware that it’s being tested. An example of a testcase:

public class SomeFacesBeanTest extends TestCase {
	private FacesContext facesContext;

	public void setUp() {
		facesContext = EasyMock.createMock(FacesContext.class);
		new MockFacesContextWrapper(facesContext);
	}

	// Your test methods.
}

I like that now the code under test does not need to be adapted. You can program as you’re used to, without writing an indirection method to wrap the static call in, or introducing a new field in every class that uses the FacesContext. How do you rank it against the solutions presented yesterday in the blog and its comments?

Share

Filed under Java, Testing | 5 Comments »



5 Responses to “Mocking Static Calls Revisited”



    Lars Vonk Says:
    Posted at: June 22, 2007 at 12:55 pm

    Good thinking Jeroen! It’s an elegant solution, you only have to write the MockFacesContextWrapper once, and like you said the program is unware of Helpers etc. so I think we have a winner.
    The issue, how to mock static calls, is still valid though. Not all static calls are implemented like FacesContext which allow for this implementation. But thanks to your blogs we can now choose from 5 different solutions :-) .

    Reply


    Lonneke Says:
    Posted at: June 23, 2007 at 12:57 pm

    I really like this solution. I agree with you that it is better not do adapt the code under test. Besides that, this solution is easy to understand for developers that need to maintain it.

    Reply


    Arnoud Wolfard Says:
    Posted at: July 25, 2007 at 3:03 pm

    Nice solution. Based on your code I came up with the code below (now you are not required to implement the abstract methods):

    public abstract class MockFacesContext extends FacesContext {

    public static void mockFacesContext(FacesContext facesContext) {
    FacesContext.setCurrentInstance(facesContext);
    }
    }

    Reply


    Meindert Says:
    Posted at: September 11, 2007 at 9:08 am

    I just read an article about a aspectJ based mocking framework that can mock private/protected and static methods/constructors: http://www.testdriven.com/modules/news/article.php?storyid=577
    Maybe that is an option?

    Reply


    Helgo Rongen Says:
    Posted at: October 25, 2007 at 2:35 pm

    You guys should also take a look at the Apache Shale Framework. It has a Test module which includes mock objects for the FacesContext.

    It works really well and all you have to do is implement the AbstractJsfTestCase from shale to get access to a (almost) fully mocked FacesContext.

    Reply


Leave a Reply

Click here to cancel reply.


Xebia Sites

  • Xebia Corporate
  • Xebia France
  • Xebia India
  • Xebia Sweden

Categories

  • Java (311)
  • Agile (181)
  • General (136)
  • Scrum (67)
  • Architecture (64)
  • Testing (59)
  • Performance (46)
  • Middleware (56)
    • Deployment (38)
  • Xebia Labs (39)
  • SOA (31)
  • Podcast (31)
  • Project Management (28)
  • Tools (26)
  • Uncategorized (20)
  • lean architecture (20)
  • Quality Assurance (17)
  • Articles (13)
  • Requirements Management (13)
  • Virtualization (19)

Tag Cloud

    Frameworks Concurrency Control Spring Hibernate SOA lean architectuur Architecture Xebia Scala Agile Groovy JPA implementation patterns product owner Ajax agile architectuur Maven Java TDD Moving to India Eclipse Lean Oracle JPA Javascript ACT Grails lean architecture Flex XML Scrum

Archives

  • February 2012
  • January 2012
  • December 2011
  • November 2011
  • October 2011
  • September 2011
  • August 2011
  • July 2011
  • June 2011
  • May 2011
  • April 2011
  • March 2011
Avatars by Sterling Adventures