001// Copyright 2006, 2007, 2008, 2009, 2010, 2011, 2012 The Apache Software Foundation 002// 003// Licensed under the Apache License, Version 2.0 (the "License"); 004// you may not use this file except in compliance with the License. 005// You may obtain a copy of the License at 006// 007// http://www.apache.org/licenses/LICENSE-2.0 008// 009// Unless required by applicable law or agreed to in writing, software 010// distributed under the License is distributed on an "AS IS" BASIS, 011// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 012// See the License for the specific language governing permissions and 013// limitations under the License. 014 015package org.apache.tapestry5.ioc.junit; 016 017import org.apache.tapestry5.ioc.annotations.Inject; 018import org.apache.tapestry5.ioc.def.ModuleDef; 019import org.junit.runner.Description; 020import org.junit.runner.Result; 021import org.junit.runner.notification.Failure; 022import org.junit.runner.notification.RunListener; 023import org.junit.runner.notification.RunNotifier; 024import org.junit.runner.notification.StoppedByUserException; 025import org.junit.runners.BlockJUnit4ClassRunner; 026import org.junit.runners.model.InitializationError; 027import org.junit.runners.model.Statement; 028 029/** 030 * <p> 031 * A JUnit4ClassRunner to help with Tapestry IOC integration tests. The test 032 * runner requires a registry configuration to be defined in a {@link Registry} 033 * annotation. A {@link RegistryShutdownType} can be specified to configure the 034 * lifecycle of the test registry and it's services 035 * </p> 036 * 037 * <p> 038 * {@link org.apache.tapestry5.ioc.junit.ModuleDef}s can be added to the 039 * {@link org.apache.tapestry5.ioc.Registry} by annotating a factory method(s) 040 * with {@link ModuleDef}. These {@link ModuleDef} factory methods must be 041 * <ul> 042 * <li>public</li> 043 * <li>static</li> 044 * <li>take zero arguments</li> 045 * <li>return a subclass of {@link org.apache.tapestry5.ioc.junit.ModuleDef}</li> 046 * </ul> 047 * </p> 048 * 049 * <p> 050 * Any services defined in the registry can be {@link Inject}ed into the test 051 * class to be used during testing. 052 * </p> 053 */ 054public class TapestryIOCJUnit4ClassRunner extends BlockJUnit4ClassRunner { 055 private final TestRegistryManager registryManager; 056 057 public TapestryIOCJUnit4ClassRunner(Class<?> type) throws InitializationError { 058 super(type); 059 this.registryManager = new TestRegistryManager(type); 060 } 061 062 @Override 063 public void run(RunNotifier notifier) { 064 RunNotifier wrapper = new RegistryManagerRunNotifier(registryManager, notifier); 065 super.run(wrapper); 066 } 067 068 @Override 069 protected Statement withAfterClasses(Statement statement) { 070 final Statement superStatement = super.withAfterClasses(statement); 071 return new Statement() { 072 @Override 073 public void evaluate() throws Throwable { 074 superStatement.evaluate(); 075 registryManager.afterTestClass(); 076 } 077 }; 078 } 079 080 @Override 081 protected Object createTest() throws Exception { 082 org.apache.tapestry5.ioc.Registry registry = registryManager.getOrCreateRegistry(); 083 return registry.autobuild(getTestClass().getJavaClass()); 084 } 085 086 public static class RegistryManagerRunNotifier extends RunNotifier { 087 private final RunNotifier delegate; 088 private final TestRegistryManager registryManager; 089 090 public RegistryManagerRunNotifier(TestRegistryManager registryManager, RunNotifier delegate) { 091 super(); 092 this.delegate = delegate; 093 this.registryManager = registryManager; 094 } 095 096 @Override 097 public void addListener(RunListener listener) { 098 delegate.addListener(listener); 099 } 100 101 @Override 102 public void removeListener(RunListener listener) { 103 delegate.removeListener(listener); 104 } 105 106 @Override 107 public void fireTestRunStarted(Description description) { 108 delegate.fireTestRunStarted(description); 109 } 110 111 @Override 112 public void fireTestRunFinished(Result result) { 113 delegate.fireTestRunFinished(result); 114 } 115 116 @Override 117 public void fireTestStarted(Description description) throws StoppedByUserException { 118 delegate.fireTestStarted(description); 119 } 120 121 @Override 122 public void fireTestFailure(Failure failure) { 123 delegate.fireTestFailure(failure); 124 } 125 126 @Override 127 public void fireTestAssumptionFailed(Failure failure) { 128 delegate.fireTestAssumptionFailed(failure); 129 } 130 131 @Override 132 public void fireTestIgnored(Description description) { 133 delegate.fireTestIgnored(description); 134 } 135 136 @Override 137 public void fireTestFinished(Description description) { 138 registryManager.afterTestMethod(); 139 delegate.fireTestFinished(description); 140 } 141 142 @Override 143 public void pleaseStop() { 144 delegate.pleaseStop(); 145 } 146 147 @Override 148 public void addFirstListener(RunListener listener) { 149 delegate.addFirstListener(listener); 150 } 151 } 152}