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