1 /*
2 * Copyright 2008 the original author or authors.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16 package org.openehealth.ipf.platform.camel.core.junit;
17
18 import java.lang.reflect.Method;
19
20 import org.junit.runner.notification.RunNotifier;
21 import org.junit.runners.model.InitializationError;
22 import org.springframework.test.annotation.DirtiesContext;
23 import org.springframework.test.context.TestExecutionListener;
24 import org.springframework.test.context.TestExecutionListeners;
25 import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
26 import org.springframework.test.context.support.DirtiesContextTestExecutionListener;
27
28 /**
29 * This test runner dirties a Spring application context after all test methods
30 * of a test class has been run.
31 * This allows test methods to use the same application context but mark it as
32 * dirty to ensure that another test class recreates the application context.
33 * <p><b>
34 * ATTENTION: Using this test runner will slow down overall test execution
35 * significantly!!! Do not use this runner if you don't really need
36 * it. Use {@link SpringJUnit4ClassRunner} instead.
37 * </b><p>
38 * Usage:
39 * <blockquote><code><pre>
40 * @RunWith(DirtySpringContextJUnit4ClassRunner.class)
41 * public class MyTest { ...
42 * </pre></code></blockquote>
43 * For this runner to work it is important the the {@link DirtiesContextTestExecutionListener}
44 * is used. By default this is the case when using this runner. If you specify
45 * the listeners explicitly via the {@link TestExecutionListeners} annotation,
46 * make sure that the {@link DirtiesContextTestExecutionListener} is included. E.g.:
47 * <blockquote><code><pre>
48 * @RunWith(DirtySpringContextJUnit4ClassRunner.class)
49 * @TestExecutionListeners({DirtiesContextTestExecutionListener.class, ...})
50 * public class MyTest { ...
51 * </pre></code></blockquote>
52 * @author Jens Riemschneider
53 */
54 public class DirtySpringContextJUnit4ClassRunner extends SpringJUnit4ClassRunner {
55
56 /**
57 * Standard constructor
58 * @param clazz
59 * see {@link SpringJUnit4ClassRunner}
60 * @throws InitializationError
61 * see {@link SpringJUnit4ClassRunner}
62 * @throws org.junit.runners.model.InitializationError
63 */
64 public DirtySpringContextJUnit4ClassRunner(Class<?> clazz)
65 throws InitializationError {
66 super(clazz);
67 }
68
69 @Override
70 public void run(RunNotifier notifier) {
71 super.run(notifier);
72 dirtyContext();
73 }
74
75 private void dirtyContext() throws AssertionError {
76 ensureDirtyContextListenerIsUsed();
77
78 // run the standard after test method listeners from the Spring JUnit4
79 // runner on a dummy test method that defines the @DirtiesContext
80 // annotation. This ensures that the DirtiesContextTestExecutionListener
81 // will be triggered and dirties the application context.
82 for (Method method : getClass().getMethods()) {
83 if (method.isAnnotationPresent(DirtiesContext.class)) {
84 try {
85 getTestContextManager().afterTestMethod(this, method, null);
86 } catch (Exception e) {
87 throw new AssertionError(e);
88 }
89 }
90 }
91 }
92
93 private void ensureDirtyContextListenerIsUsed() {
94 for (TestExecutionListener listener : getTestContextManager().getTestExecutionListeners()) {
95 if (listener instanceof DirtiesContextTestExecutionListener) {
96 return;
97 }
98 }
99
100 throw new AssertionError(
101 "DirtiesContextTestExecutionListener must be added when using DirtySpringContextJUnit4ClassRunner");
102 }
103
104 @DirtiesContext
105 public void dirtyContextDummy() {
106 // Does nothing. But ensures that the annotation is interpreted by
107 // afterTestMethod
108 }
109 }