Mocking JSF's FacesContext
When you are in a JSF application and you want to write tests for your view beans, you will very likely come into the situation of having to mock JSF’s FacesContext. The
FacesContext is a central class in JSF, providing methods for doing redirects, adding messages shown to the user and giving acceess to the “external context”, which in turn provides access to HTTP related functionality.
In one of my projects we are using Mockito as our mocking library of choice. If you do not know Mockito, a good introduction can be found on the project homepage.
Once you get to the point to mock
FacesContext, you get into a dilemma. Mockito does not allow to mock static methods. But instead of using an extension library like PowerMock you can also go another route.
For JSF projects, it is nearly impossible to go without OmniFaces. OmniFaces is a libary offering various adaptions and extensions commonly needed in JSF projects. You can almost certainly throw OmniFaces on your JSF project’s classpath, it will be needed at some point.
One of the classes provided by OmniFaces is
org.omnifaces.util.Faces (JavaDoc). It is basically a collection of utility methods for conveniently accessing certain functionality from JSF’s
FacesContext. For example, you can do a redirect in your view bean like in the following example
or get some value from the underlying HTTP session
I think you get the gist of it.
Coming back to our mocking problem, one of the methods provided by
Faces is the
setContext(FacesContext context) method. This method was introduced to coveniently replace the current
FacesContext instance with some wrapper implementation.
But this means when we use OmniFaces’s
Faces class instead of the JSF
FacesContext in our code base, it gets easy to mock those places in our unit tests.
Let’s assume we have this method in one of our view classes
As we use OmniFaces’s
Faces class we can conveniently set the mocked
FacesContext as current instance in our test-case:
As you can see, in JUnit’s
@Before method we do some wiring to mock out all the relevant parts. Starting from
FacesContext down to the actual
HttpServletRequest. The test-case above uses some nice Mockito features like it’s JUnit runner supporting the
@Mock annotation to do automatic mocking.
Another useful element is Mockito’s ArgumentCaptor. It is used to capture the redirect URL we are getting as an argument when
ExternalContext.redirect(String) is called.
However, the key element is this line
Faces class is used throught your code base, only this line is needed to start going with your mocking library/approach of choice.
In this article we showed how the usage of OmniFaces’
Faces class can make mocking of JSF’s
FacesContext very easy. We use Mockito in the test examples to do the actual mocking work, however, the groundwork is laid by OmniFaces.