Seam and JUnit
dahm Oct 18, 2006 3:42 AMHi,
I tried to get Seam tests running with JUnit. As a first approach I took one
of the NG-Tests from the examples and tried to adapt it:
public class SeamTest extends TestCase { private MockExternalContext externalContext; private MockServletContext servletContext; private MockApplication application; private SeamPhaseListener phases; private MockFacesContext facesContext; private MockHttpSession session; private Map<String, ConversationState> conversationStates; protected void setUp() throws Exception { init(); begin(); } protected void tearDown() throws Exception { end(); cleanup(); } public void testDefault() throws Exception { new Script() { @Override protected void updateModelValues() throws Exception { User user = (User) Component.getInstance("user", true); assert user!=null; user.setUserName("1ovthafew"); user.setPassword("secret"); user.setRealName("Gavin King"); } @Override protected void invokeApplication() { LoginAction register = (LoginAction) Component.getInstance("login", true); String outcome = register.login(); assert "success".equals( outcome ); } @Override protected void renderResponse() { User user = (User) Component.getInstance("user", false); assert user!=null; assert user.getRealName().equals("Gavin King"); assert user.getUserName().equals("1ovthafew"); assert user.getPassword().equals(null); } }.run(); } protected HttpSession getSession() { return (HttpSession) externalContext.getSession(true); } protected boolean isSessionInvalid() { return ( (MockHttpSession) getSession() ).isInvalid(); } protected FacesContext getFacesContext() { return facesContext; } /** * Script is an abstract superclass for usually anonymous * inner classes that test JSF interactions. * * @author Gavin King */ public abstract class Script { private String conversationId; private String outcome; private boolean validationFailed; /** * A script for a JSF interaction with * no existing long-running conversation. */ protected Script() {} /** * A script for a JSF interaction in the * scope of an existing long-running * conversation. */ protected Script(String id) { conversationId = id; } protected boolean isGetRequest() { return false; } protected String getViewId() { return null; } /** * Helper method for resolving components in * the test script. */ protected Object getInstance(Class clazz) { return Component.getInstance(clazz, true); } /** * Helper method for resolving components in * the test script. */ protected Object getInstance(String name) { return Component.getInstance(name, true); } /** * Override to implement the interactions between * the JSF page and your components that occurs * during the apply request values phase. */ protected void applyRequestValues() throws Exception {} /** * Override to implement the interactions between * the JSF page and your components that occurs * during the process validations phase. */ protected void processValidations() throws Exception {} /** * Override to implement the interactions between * the JSF page and your components that occurs * during the update model values phase. */ protected void updateModelValues() throws Exception {} /** * Override to implement the interactions between * the JSF page and your components that occurs * during the invoke application phase. */ protected void invokeApplication() throws Exception {} protected void setOutcome(String outcome) { this.outcome = outcome; } protected String getInvokeApplicationOutcome() { return outcome; } /** * Override to implement the interactions between * the JSF page and your components that occurs * during the render response phase. */ protected void renderResponse() throws Exception {} /** * Override to set up any request parameters for * the request. */ protected void setup() {} public Map<String, String[]> getParameters() { return ( (MockHttpServletRequest) externalContext.getRequest() ).getParameters(); } public Map<String, String[]> getHeaders() { return ( (MockHttpServletRequest) externalContext.getRequest() ).getHeaders(); } protected void validate(Class modelClass, String property, Object value) { ClassValidator validator = Validation.getValidator(modelClass); InvalidValue[] ivs = validator.getPotentialInvalidValues(property, value); if (ivs.length>0) { validationFailed = true; FacesMessage message = FacesMessages.createFacesMessage( FacesMessage.SEVERITY_WARN, ivs[0].getMessage() ); FacesContext.getCurrentInstance().addMessage( property, /*TODO*/ message ); FacesContext.getCurrentInstance().renderResponse(); } } public boolean isValidationFailure() { return validationFailed; } @SuppressWarnings("unchecked") public String run() throws Exception { externalContext = new MockExternalContext(servletContext, session); facesContext = new MockFacesContext( externalContext, application ); facesContext.setCurrent(); Map attributes = facesContext.getViewRoot().getAttributes(); if ( !isGetRequest() && conversationId!=null ) { if ( conversationStates.containsKey( conversationId ) ) { attributes.putAll( conversationStates.get( conversationId ).state ); } } setup(); facesContext.getViewRoot().setViewId( getViewId() ); phases.beforePhase( new PhaseEvent(facesContext, PhaseId.RESTORE_VIEW, MockLifecycle.INSTANCE) ); phases.afterPhase( new PhaseEvent(facesContext, PhaseId.RESTORE_VIEW, MockLifecycle.INSTANCE) ); if ( !isGetRequest() ) { phases.beforePhase( new PhaseEvent(facesContext, PhaseId.APPLY_REQUEST_VALUES, MockLifecycle.INSTANCE) ); applyRequestValues(); phases.afterPhase( new PhaseEvent(facesContext, PhaseId.APPLY_REQUEST_VALUES, MockLifecycle.INSTANCE) ); phases.beforePhase( new PhaseEvent(facesContext, PhaseId.PROCESS_VALIDATIONS, MockLifecycle.INSTANCE) ); processValidations(); phases.afterPhase( new PhaseEvent(facesContext, PhaseId.PROCESS_VALIDATIONS, MockLifecycle.INSTANCE) ); if ( !FacesContext.getCurrentInstance().getRenderResponse() ) { phases.beforePhase( new PhaseEvent(facesContext, PhaseId.UPDATE_MODEL_VALUES, MockLifecycle.INSTANCE) ); updateModelValues(); phases.afterPhase( new PhaseEvent(facesContext, PhaseId.UPDATE_MODEL_VALUES, MockLifecycle.INSTANCE) ); phases.beforePhase( new PhaseEvent(facesContext, PhaseId.INVOKE_APPLICATION, MockLifecycle.INSTANCE) ); invokeApplication(); String outcome = getInvokeApplicationOutcome(); facesContext.getApplication().getNavigationHandler().handleNavigation(facesContext, null, outcome); phases.afterPhase( new PhaseEvent(facesContext, PhaseId.INVOKE_APPLICATION, MockLifecycle.INSTANCE) ); } } if ( !FacesContext.getCurrentInstance().getResponseComplete() ) { phases.beforePhase( new PhaseEvent(facesContext, PhaseId.RENDER_RESPONSE, MockLifecycle.INSTANCE) ); //TODO: hackish workaround for the fact that page actions don't get called! if ( isGetRequest() ) { Lifecycle.setPhaseId(PhaseId.INVOKE_APPLICATION); invokeApplication(); Lifecycle.setPhaseId(PhaseId.RENDER_RESPONSE); } renderResponse(); facesContext.getApplication().getStateManager().saveSerializedView(facesContext); phases.afterPhase( new PhaseEvent(facesContext, PhaseId.RENDER_RESPONSE, MockLifecycle.INSTANCE ) ); } Map pageContextMap = (Map) attributes.get( ScopeType.PAGE.getPrefix() ); if (pageContextMap!=null) { conversationId = (String) pageContextMap.get(Manager.CONVERSATION_ID); ConversationState conversationState = new ConversationState(); conversationState.state.putAll( attributes ); conversationStates.put( conversationId, conversationState ); } return conversationId; } } public void begin() { session = new MockHttpSession(servletContext); } public void end() { Lifecycle.endSession( servletContext, new ServletSessionImpl(session) ); session = null; } /** * Create a SeamPhaseListener by default. Override to use * one of the other standard Seam phase listeners. */ protected SeamPhaseListener createPhaseListener() { return new SeamPhaseListener(); } public void init() throws Exception { application = new MockApplication(); application.setStateManager( new SeamStateManager( application.getStateManager() ) ); application.setNavigationHandler( new SeamNavigationHandler( application.getNavigationHandler() ) ); //don't need a SeamVariableResolver, because we don't test the view phases = createPhaseListener(); servletContext = new MockServletContext(); initServletContext( servletContext.getInitParameters() ); new Initialization(servletContext).init(); Lifecycle.setServletContext(servletContext); conversationStates = new HashMap<String, ConversationState>(); } public void cleanup() throws Exception { Lifecycle.endApplication(servletContext); externalContext = null; conversationStates.clear(); conversationStates = null; } /** * Override to set up any servlet context attributes. */ public void initServletContext(Map initParams) {} private class ConversationState { Map state = new HashMap(); } protected InitialContext getInitialContext() throws NamingException { return Naming.getInitialContext(); } protected UserTransaction getUserTransaction() throws NamingException { return Transactions.getUserTransaction(); } protected Object getField(Object object, String fieldName) { try { Field declaredField = object.getClass().getDeclaredField(fieldName); if ( !declaredField.isAccessible() ) declaredField.setAccessible(true); return declaredField.get(object); } catch (Exception e) { throw new IllegalArgumentException("could not get field value: " + fieldName, e); } } protected void setField(Object object, String fieldName, Object value) { try { Field declaredField = object.getClass().getDeclaredField(fieldName); if ( !declaredField.isAccessible() ) declaredField.setAccessible(true); declaredField.set(object, value); } catch (Exception e) { throw new IllegalArgumentException("could not set field value: " + fieldName, e); } } }
I'm not sure what's wrong with it, all I get is:
java.lang.AssertionError at de.kvbb.ingver.test.SeamTest$1.updateModelValues(SeamTest.java:72) at de.kvbb.ingver.test.SeamTest$Script.run(SeamTest.java:280) at de.kvbb.ingver.test.SeamTest.testDefault(SeamTest.java:96) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) at java.lang.reflect.Method.invoke(Method.java:585) at junit.framework.TestCase.runTest(TestCase.java:154) at junit.framework.TestCase.runBare(TestCase.java:127) at junit.framework.TestResult$1.protect(TestResult.java:106) at junit.framework.TestResult.runProtected(TestResult.java:124) at junit.framework.TestResult.run(TestResult.java:109) at junit.framework.TestCase.run(TestCase.java:118) at junit.framework.TestSuite.runTest(TestSuite.java:208) at junit.framework.TestSuite.run(TestSuite.java:203) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:478) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:344) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:196)
Thanks in advance
Markus