• 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/Bookmark

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 :-) .



    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.



    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);
    }
    }



    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?



    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.



Leave a Reply

Click here to cancel reply.

Deployment automation for Java application running on Websphere, WebLogic and JBoss

Archives

  • March 2010
  • February 2010
  • January 2010
  • December 2009
  • November 2009
  • October 2009
  • September 2009
  • August 2009
  • July 2009
  • June 2009
  • May 2009
  • April 2009

Xebia Sites

  • Xebia Corporate
  • Xebia France
  • Xebia India

Categories

  • Java (282)
  • Agile (109)
  • General (50)
  • Testing (42)
  • Performance (42)
  • Hibernate (36)
  • Scrum (33)
  • Podcast (31)
  • Architecture (31)
  • Spring (28)
  • SOA (24)
  • Maven (22)
  • Project Management (22)
  • Middleware (23)
    • Deployment (14)
  • Flex (17)
  • JPA (17)
  • Eclipse (15)
  • Xebia Labs (15)
  • Quality Assurance (14)

Tag Cloud

    Scala Agile Awareness Workshop Ajax Seam Testing Functional Programming Groovy XML Architecture Java Maven Lean qcon Spring esb product owner Grails Hibernate fitnesse Xebia Introduction to Agile IntelliJ Agile Closures JavaOne Performance Semantic Web Poppendieck SOA Scrum