-
1. Re: Mock FacesContext in Spring Application Context?
ilya_shaikovsky Apr 27, 2010 5:00 AM (in response to robertmarkbram)moving to RichFaces space from RichFaces development.
-
2. Re: Mock FacesContext in Spring Application Context?
nbelaevski Apr 27, 2010 1:49 PM (in response to robertmarkbram)Hi Robert,
Can you please post test code?
-
3. Re: Mock FacesContext in Spring Application Context?
robertmarkbram Apr 27, 2010 7:55 PM (in response to nbelaevski)Hi Nick,
Here is an extract from my spring bean that has a @PostConstruct method that depends on FacesContext.
@Component("headerBean")@Scope("request")public class HeaderBean {@PostConstructpublic void init() {String headerId = FacesContext.getCurrentInstance().getExternalContext().getSessionMap().get("headerID");....}}This is a "view bean" (would be a managed bean if we were using pure JSF) and the intention that is that each time the view is loaded (each new request), the bean looks up headerId in the session. In the running application, this doesn't fail. In unit tests, it fails with the following exception:org.unitils.core.UnitilsException: Unable to create application context for locations [classpath:testApplicationContext.xml, classpath:data-access-config.xml]at org.unitils.spring.util.ApplicationContextManager.createInstanceForValues(ApplicationContextManager.java:121)at org.unitils.spring.util.ApplicationContextManager.createInstanceForValues(ApplicationContextManager.java:36)....Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'headerBean': Invocation of init method failed; nested exception is java.lang.NullPointerExceptionat org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor.postProcessBeforeInitialization(InitDestroyAnnotationBeanPostProcessor.java:133)at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyBeanPostProcessorsBeforeInitialization(AbstractAutowireCapableBeanFactory.java:394)... 29 moreCaused by: java.lang.NullPointerExceptionat au.com.tgg.roq.view.beans.HeaderBean.init(HeaderBean.java:135)... 41 moreWith a bit further testing, I find that HeaderBean.init(HeaderBean.java:135) refers to FacesContext.getCurrentInstance() being null.
1) The exact same error also occurs for any other unit test that uses a Spring Application Context, even if it never refers to HeaderBean. I wondered why is Spring instantiating all the beans at once and is this a Unitils issue instead? I asked that question on their forum (https://sourceforge.net/projects/unitils/forums/forum/570578/topic/3685714) and Tim answered "Unitils only creates a classpath xml application context, the rest is done by Spring."
2) So, how can I inject a mock FacesContext into the Spring context? This error occurs before @Before in unit tests, so I can't avoid this issue by mocking the context in code.
3) Alternatively, I can remove @PostConstruct from the init() method and call it in the JSP with: #{headerBean.init()}. This works too but feels hacky, plus I have to adjust unit tests to call init() all the time..
4) Alternatively I can completely ignore the issue and put a null check in the init() method: a) the running app always has a Context at runtime so it's fine and b) mock a FacesContext in @Before and make sure init() is called "manually" again.
Hope this detail is clear enough and not too much info.
Thanks,
Rob
-
4. Re: Mock FacesContext in Spring Application Context?
nbelaevski Apr 28, 2010 11:21 AM (in response to robertmarkbram)Ok, that's bean code, but can you please post test code so that I can see how Mock objects are being configured there and try to reproduce the problem locally?