All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.jboss.test.faces.mockito.runner.FacesMockitoRunner Maven / Gradle / Ivy

The newest version!
/*
 * JBoss, Home of Professional Open Source
 * Copyright 2011, Red Hat, Inc. and individual contributors
 * by the @authors tag. See the copyright.txt in the distribution for a
 * full listing of individual contributors.
 *
 * This is free software; you can redistribute it and/or modify it
 * under the terms of the GNU Lesser General Public License as
 * published by the Free Software Foundation; either version 2.1 of
 * the License, or (at your option) any later version.
 *
 * This software is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this software; if not, write to the Free
 * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
 * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
 */
package org.jboss.test.faces.mockito.runner;

import static org.jboss.test.faces.annotation.Environment.Feature.APPLICATION;
import static org.jboss.test.faces.annotation.Environment.Feature.EL_CONTEXT;
import static org.jboss.test.faces.annotation.Environment.Feature.EXTERNAL_CONTEXT;
import static org.jboss.test.faces.annotation.Environment.Feature.FACES_CONTEXT;
import static org.jboss.test.faces.annotation.Environment.Feature.FACTORIES;
import static org.jboss.test.faces.annotation.Environment.Feature.RENDER_KIT;
import static org.jboss.test.faces.annotation.Environment.Feature.RESPONSE_WRITER;
import static org.jboss.test.faces.annotation.Environment.Feature.SERVLET_REQUEST;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;

import javax.el.ELContext;
import javax.faces.application.Application;
import javax.faces.application.ApplicationFactory;
import javax.faces.application.ViewHandler;
import javax.faces.context.ExceptionHandlerFactory;
import javax.faces.context.ExternalContext;
import javax.faces.context.ExternalContextFactory;
import javax.faces.context.FacesContext;
import javax.faces.context.FacesContextFactory;
import javax.faces.context.PartialViewContextFactory;
import javax.faces.lifecycle.LifecycleFactory;
import javax.faces.render.RenderKit;
import javax.faces.render.RenderKitFactory;
import javax.faces.render.ResponseStateManager;
import javax.faces.view.facelets.TagHandlerDelegateFactory;
import javax.inject.Inject;
import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.jboss.test.faces.annotation.Environment;
import org.jboss.test.faces.mockito.MockFacesEnvironment;
import org.jboss.test.faces.writer.RecordingResponseWriter;
import org.junit.internal.runners.model.MultipleFailureException;
import org.junit.runner.notification.RunNotifier;
import org.junit.runners.BlockJUnit4ClassRunner;
import org.junit.runners.model.FrameworkMethod;
import org.junit.runners.model.InitializationError;
import org.junit.runners.model.Statement;
import org.mockito.MockitoAnnotations;
import org.mockito.internal.runners.util.FrameworkUsageValidator;
import org.mockito.runners.MockitoJUnitRunner;

/**
 * 

* JUnit runner for running mocked JSF environment. *

* *

* It initialized {@link MockFacesEnvironment} and is able to inject mocked JSF classes held by {@link MockFacesEnvironment} to * current test instance. *

* *

* Similarly to {@link MockitoJUnitRunner}, it uses {@link MockitoAnnotations#initMocks(Object)} on test instance to mock all * the test dependencies annotated by Mockito annotations. *

* * * TODO cleanup of injections * * TODO create tests for failures * * @author Lukas Fryc */ public class FacesMockitoRunner extends BlockJUnit4ClassRunner { /** The mocked JSF environment. */ private MockFacesEnvironment environment; /** * Instantiates a new faces mockito runner. * * @param klass the class * @throws InitializationError the initialization error */ public FacesMockitoRunner(Class klass) throws InitializationError { super(klass); } /* * (non-Javadoc) * * @see org.junit.runners.ParentRunner#run(org.junit.runner.notification.RunNotifier) */ @Override public void run(RunNotifier notifier) { notifier.addListener(new FrameworkUsageValidator(notifier)); super.run(notifier); } @Override protected Statement withBefores(final FrameworkMethod method, final Object target, final Statement originalStatement) { final Statement onlyBefores = super.withBefores(method, target, new EmptyStatement()); return new Statement() { @Override public void evaluate() throws Throwable { runBefore(target); onlyBefores.evaluate(); originalStatement.evaluate(); } }; } @Override protected Statement withAfters(final FrameworkMethod method, final Object target, final Statement originalStatement) { final Statement onlyAfters = super.withAfters(method, target, new EmptyStatement()); final Statement runnerAfters = new Statement() { @Override public void evaluate() throws Throwable { runAfter(target); } }; return new Statement() { @Override public void evaluate() throws Throwable { multiExecute(originalStatement, onlyAfters, runnerAfters); } }; } /** * Run before each test * * @param target the target test instance */ protected void runBefore(Object target) { MockitoAnnotations.initMocks(target); environment = new MockFacesEnvironment(); processInjections(target); processFeatures(target); } /** * Run after each test * * @param target the target test instance */ protected void runAfter(Object target) { environment.release(); environment = null; } /** * Process features. * * @param target the target test instance */ private void processFeatures(Object target) { Environment annotation = target.getClass().getAnnotation(Environment.class); Environment.Feature[] features = new Environment.Feature[0]; if (annotation != null) { features = annotation.value(); } for (Environment.Feature feature : features) { initializeFeature(feature); } } /** * Process injections. * * @param target the target test instance */ private void processInjections(Object target) { for (Class clazz = target.getClass(); clazz != Object.class; clazz = clazz.getSuperclass()) { for (Field field : clazz.getDeclaredFields()) { if (field.getAnnotation(Inject.class) != null) { Object injection = getInjection(field.getType()); if (injection != null) { inject(field, target, injection); } } } } } /** * Injects the given injection to field of target test instance. * * @param field the field * @param target the target * @param injection the injection */ private void inject(Field field, Object target, Object injection) { boolean accessible = field.isAccessible(); if (!accessible) { field.setAccessible(true); } try { field.set(target, injection); } catch (Exception e) { throw new IllegalStateException("Cannot inject value to " + field, e); } if (!accessible) { field.setAccessible(false); } } /** * Initialize feature with currenct mocked environment * * @param feature the feature */ private void initializeFeature(Environment.Feature feature) { switch (feature) { case FACTORIES: environment.withFactories(); break; case APPLICATION: environment.withApplication(); break; case EL_CONTEXT: environment.withELContext(); break; case EXTERNAL_CONTEXT: environment.withExternalContext(); break; case RENDER_KIT: environment.withRenderKit(); break; case RESPONSE_WRITER: environment.withResponseWriter(); break; case SERVLET_REQUEST: environment.withServletRequest(); break; default: break; } } /** *

* Tries to get mock for given type. *

* *

* Before injecting, it initializes all dependencies needed by given mock type by initializing given feature. *

* * @param type the JSF class type to initialized and inject * @return the injection or null if given type ais unknown */ private Object getInjection(Class type) { if (type == MockFacesEnvironment.class) { return environment; } if (type == FacesContext.class) { initializeFeature(FACES_CONTEXT); return environment.getFacesContext(); } if (type == Application.class) { initializeFeature(APPLICATION); return environment.getApplication(); } if (type == ELContext.class) { initializeFeature(EL_CONTEXT); return environment.getElContext(); } if (type == ApplicationFactory.class) { initializeFeature(FACTORIES); return environment.getApplicationFactory(); } if (type == ServletContext.class) { initializeFeature(SERVLET_REQUEST); return environment.getServletContext(); } if (type == ExceptionHandlerFactory.class) { initializeFeature(FACTORIES); return environment.getExceptionHandlerFactory(); } if (type == ExternalContext.class) { initializeFeature(EXTERNAL_CONTEXT); return environment.getExternalContext(); } if (type == ExternalContextFactory.class) { initializeFeature(FACTORIES); return environment.getExternalContextFactory(); } if (type == FacesContextFactory.class) { initializeFeature(FACTORIES); return environment.getFacesContextFactory(); } if (type == LifecycleFactory.class) { initializeFeature(FACTORIES); return environment.getLifecycleFactory(); } if (type == PartialViewContextFactory.class) { initializeFeature(FACTORIES); return environment.getPartialViewContextFactory(); } if (type == RenderKit.class) { initializeFeature(RENDER_KIT); return environment.getRenderKit(); } if (type == RenderKitFactory.class) { initializeFeature(FACTORIES); return environment.getRenderKitFactory(); } if (type == HttpServletRequest.class) { initializeFeature(SERVLET_REQUEST); return environment.getRequest(); } if (type == HttpServletResponse.class) { initializeFeature(SERVLET_REQUEST); return environment.getResponse(); } if (type == ResponseStateManager.class) { initializeFeature(RENDER_KIT); return environment.getResponseStateManager(); } if (RecordingResponseWriter.class.isAssignableFrom(type)) { initializeFeature(RESPONSE_WRITER); return environment.getResponseWriter(); } if (type == TagHandlerDelegateFactory.class) { initializeFeature(FACTORIES); return environment.getTagHandlerDelegateFactory(); } if (type == ViewHandler.class) { initializeFeature(APPLICATION); return environment.getViewHandler(); } return null; } /** * A helper to safely execute multiple statements in one.
* * Will execute all statements even if they fail, all exceptions will be kept. If multiple {@link Statement}s fail, a * {@link MultipleFailureException} will be thrown. * * @author Aslak Knutsen * @version $Revision: $ */ private void multiExecute(Statement... statements) throws Throwable { List exceptions = new ArrayList(); for (Statement command : statements) { try { command.evaluate(); } catch (Exception e) { exceptions.add(e); } } if (exceptions.isEmpty()) { return; } if (exceptions.size() == 1) { throw exceptions.get(0); } throw new MultipleFailureException(exceptions); } private static class EmptyStatement extends Statement { @Override public void evaluate() throws Throwable { } } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy