EMMA Coverage Report (generated Thu May 22 12:08:10 CDT 2014)
[all classes][org.springframework.batch.test]

COVERAGE SUMMARY FOR SOURCE FILE [StepScopeTestExecutionListener.java]

nameclass, %method, %block, %line, %
StepScopeTestExecutionListener.java100% (2/2)100% (11/11)88%  (206/234)90%  (44.3/49)

COVERAGE BREAKDOWN BY CLASS AND METHOD

nameclass, %method, %block, %line, %
     
class StepScopeTestExecutionListener$ExtractorMethodCallback100% (1/1)100% (3/3)86%  (36/42)94%  (10.3/11)
doWith (Method): void 100% (1/1)71%  (15/21)87%  (4.3/5)
StepScopeTestExecutionListener$ExtractorMethodCallback (StepScopeTestExecutio... 100% (1/1)100% (12/12)100% (5/5)
getName (): String 100% (1/1)100% (9/9)100% (1/1)
     
class StepScopeTestExecutionListener100% (1/1)100% (8/8)89%  (170/192)89%  (34/38)
getStepExecution (TestContext): StepExecution 100% (1/1)67%  (44/66)75%  (12/16)
<static initializer> 100% (1/1)100% (11/11)100% (1/1)
StepScopeTestExecutionListener (): void 100% (1/1)100% (3/3)100% (2/2)
afterTestClass (TestContext): void 100% (1/1)100% (1/1)100% (1/1)
afterTestMethod (TestContext): void 100% (1/1)100% (26/26)100% (5/5)
beforeTestClass (TestContext): void 100% (1/1)100% (1/1)100% (1/1)
beforeTestMethod (TestContext): void 100% (1/1)100% (49/49)100% (7/7)
prepareTestInstance (TestContext): void 100% (1/1)100% (35/35)100% (5/5)

1/*
2 * Copyright 2006-2014 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 */
16package org.springframework.batch.test;
17 
18import java.lang.reflect.Method;
19 
20import org.springframework.batch.core.StepExecution;
21import org.springframework.batch.core.scope.context.StepContext;
22import org.springframework.batch.core.scope.context.StepSynchronizationManager;
23import org.springframework.batch.item.adapter.HippyMethodInvoker;
24import org.springframework.test.context.TestContext;
25import org.springframework.test.context.TestExecutionListener;
26import org.springframework.util.ReflectionUtils;
27import org.springframework.util.ReflectionUtils.MethodCallback;
28 
29/**
30 * A {@link TestExecutionListener} that sets up step-scope context for
31 * dependency injection into unit tests. A {@link StepContext} will be created
32 * for the duration of a test method and made available to any dependencies that
33 * are injected. The default behaviour is just to create a {@link StepExecution}
34 * with fixed properties. Alternatively it can be provided by the test case as a
35 * factory methods returning the correct type.  Example:
36 * 
37 * <pre>
38 * &#064;ContextConfiguration
39 * &#064;TestExecutionListeners( { DependencyInjectionTestExecutionListener.class, StepScopeTestExecutionListener.class })
40 * &#064;RunWith(SpringJUnit4ClassRunner.class)
41 * public class StepScopeTestExecutionListenerIntegrationTests {
42 * 
43 *         // A step-scoped dependency configured in the ApplicationContext
44 *         &#064;Autowired
45 *         private ItemReader&lt;String&gt; reader;
46 * 
47 *  public StepExecution getStepExecution() {
48 *    StepExecution execution = MetaDataInstanceFactory.createStepExecution();
49 *    execution.getExecutionContext().putString("foo", "bar");
50 *    return execution;
51 *  }
52 * 
53 *         &#064;Test
54 *         public void testStepScopedReader() {
55 *                 // Step context is active here so the reader can be used,
56 *      // and the step execution context will contain foo=bar...
57 *                 assertNotNull(reader.read());
58 *         }
59 * 
60 * }
61 * </pre>
62 * 
63 * @author Dave Syer
64 * @author Chris Schaefer
65 */
66public class StepScopeTestExecutionListener implements TestExecutionListener {
67        private static final String STEP_EXECUTION = StepScopeTestExecutionListener.class.getName() + ".STEP_EXECUTION";
68        private static final String SET_ATTRIBUTE_METHOD_NAME = "setAttribute";
69        private static final String HAS_ATTRIBUTE_METHOD_NAME = "hasAttribute";
70        private static final String GET_ATTRIBUTE_METHOD_NAME = "getAttribute";
71        private static final String GET_TEST_INSTANCE_METHOD = "getTestInstance";
72 
73        /**
74         * Set up a {@link StepExecution} as a test context attribute.
75         * 
76         * @param testContext the current test context
77         * @throws Exception if there is a problem
78         * @see TestExecutionListener#prepareTestInstance(TestContext)
79         */
80        @Override
81        public void prepareTestInstance(TestContext testContext) throws Exception {
82                StepExecution stepExecution = getStepExecution(testContext);
83 
84                if (stepExecution != null) {
85                        Method method = TestContext.class.getMethod(SET_ATTRIBUTE_METHOD_NAME, String.class, Object.class);
86                        ReflectionUtils.invokeMethod(method, testContext, STEP_EXECUTION, stepExecution);
87                }
88        }
89 
90        /**
91         * @param testContext the current test context
92         * @throws Exception if there is a problem
93         * @see TestExecutionListener#beforeTestMethod(TestContext)
94         */
95        @Override
96        public void beforeTestMethod(TestContext testContext) throws Exception {
97                Method hasAttributeMethod = TestContext.class.getMethod(HAS_ATTRIBUTE_METHOD_NAME, String.class);
98                Boolean hasAttribute = (Boolean) ReflectionUtils.invokeMethod(hasAttributeMethod, testContext, STEP_EXECUTION);
99 
100                if (hasAttribute) {
101                        Method method = TestContext.class.getMethod(GET_ATTRIBUTE_METHOD_NAME, String.class);
102                        StepExecution stepExecution = (StepExecution) ReflectionUtils.invokeMethod(method, testContext, STEP_EXECUTION);
103 
104                        StepSynchronizationManager.register(stepExecution);
105                }
106        }
107 
108        /**
109         * @param testContext the current test context
110         * @throws Exception if there is a problem
111         * @see TestExecutionListener#afterTestMethod(TestContext)
112         */
113        @Override
114        public void afterTestMethod(TestContext testContext) throws Exception {
115                Method method = TestContext.class.getMethod(HAS_ATTRIBUTE_METHOD_NAME, String.class);
116                Boolean hasAttribute = (Boolean) ReflectionUtils.invokeMethod(method, testContext, STEP_EXECUTION);
117 
118                if (hasAttribute) {
119                        StepSynchronizationManager.close();
120                }
121        }
122 
123        /*
124         * Support for Spring 3.0 (empty).
125         */
126        @Override
127        public void afterTestClass(TestContext testContext) throws Exception {
128        }
129 
130        /*
131         * Support for Spring 3.0 (empty).
132         */
133        @Override
134        public void beforeTestClass(TestContext testContext) throws Exception {
135        }
136        
137        /**
138         * Discover a {@link StepExecution} as a field in the test case or create
139         * one if none is available.
140         * 
141         * @param testContext the current test context
142         * @return a {@link StepExecution}
143         */
144        protected StepExecution getStepExecution(TestContext testContext) {
145                Object target;
146 
147                try {
148                        Method method = TestContext.class.getMethod(GET_TEST_INSTANCE_METHOD);
149                        target = ReflectionUtils.invokeMethod(method, testContext);
150                } catch (NoSuchMethodException e) {
151                        throw new IllegalStateException("No such method " + GET_TEST_INSTANCE_METHOD + " on provided TestContext", e);
152                }
153 
154                ExtractorMethodCallback method = new ExtractorMethodCallback(StepExecution.class, "getStepExecution");
155                ReflectionUtils.doWithMethods(target.getClass(), method);
156                if (method.getName() != null) {
157                        HippyMethodInvoker invoker = new HippyMethodInvoker();
158                        invoker.setTargetObject(target);
159                        invoker.setTargetMethod(method.getName());
160                        try {
161                                invoker.prepare();
162                                return (StepExecution) invoker.invoke();
163                        }
164                        catch (Exception e) {
165                                throw new IllegalArgumentException("Could not create step execution from method: " + method.getName(),
166                                                e);
167                        }
168                }
169 
170                return MetaDataInstanceFactory.createStepExecution();
171        }
172 
173        /**
174         * Look for a method returning the type provided, preferring one with the
175         * name provided.
176         */
177        private final class ExtractorMethodCallback implements MethodCallback {
178                private String preferredName;
179 
180                private final Class<?> preferredType;
181 
182                private Method result;
183 
184                public ExtractorMethodCallback(Class<?> preferredType, String preferredName) {
185                        super();
186                        this.preferredType = preferredType;
187                        this.preferredName = preferredName;
188                }
189 
190                public String getName() {
191                        return result == null ? null : result.getName();
192                }
193 
194                @Override
195                public void doWith(Method method) throws IllegalArgumentException, IllegalAccessException {
196                        Class<?> type = method.getReturnType();
197                        if (preferredType.isAssignableFrom(type)) {
198                                if (result == null || method.getName().equals(preferredName)) {
199                                        result = method;
200                                }
201                        }
202                }
203        }
204}

[all classes][org.springframework.batch.test]
EMMA 2.0.5312 (C) Vladimir Roubtsov