001/* 002 * Copyright 2002-2015 the original author or authors. 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * https://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016 017package org.springframework.test.context.junit4.statements; 018 019import java.lang.reflect.Method; 020import java.util.ArrayList; 021import java.util.List; 022 023import org.junit.runners.model.MultipleFailureException; 024import org.junit.runners.model.Statement; 025 026import org.springframework.test.context.TestContextManager; 027 028/** 029 * {@code RunAfterTestMethodCallbacks} is a custom JUnit {@link Statement} which allows 030 * the <em>Spring TestContext Framework</em> to be plugged into the JUnit execution chain 031 * by calling {@link TestContextManager#afterTestMethod afterTestMethod()} on the supplied 032 * {@link TestContextManager}. 033 * 034 * <p><strong>NOTE:</strong> This class requires JUnit 4.9 or higher. 035 * 036 * @author Sam Brannen 037 * @since 3.0 038 * @see #evaluate() 039 * @see RunBeforeTestMethodCallbacks 040 */ 041public class RunAfterTestMethodCallbacks extends Statement { 042 043 private final Statement next; 044 045 private final Object testInstance; 046 047 private final Method testMethod; 048 049 private final TestContextManager testContextManager; 050 051 052 /** 053 * Construct a new {@code RunAfterTestMethodCallbacks} statement. 054 * @param next the next {@code Statement} in the execution chain 055 * @param testInstance the current test instance (never {@code null}) 056 * @param testMethod the test method which has just been executed on the 057 * test instance 058 * @param testContextManager the TestContextManager upon which to call 059 * {@code afterTestMethod()} 060 */ 061 public RunAfterTestMethodCallbacks(Statement next, Object testInstance, Method testMethod, 062 TestContextManager testContextManager) { 063 064 this.next = next; 065 this.testInstance = testInstance; 066 this.testMethod = testMethod; 067 this.testContextManager = testContextManager; 068 } 069 070 071 /** 072 * Evaluate the next {@link Statement} in the execution chain (typically an instance of 073 * {@link org.junit.internal.runners.statements.RunAfters RunAfters}), catching any 074 * exceptions thrown, and then invoke 075 * {@link TestContextManager#afterTestMethod(Object, Method, Throwable)} supplying the 076 * first caught exception (if any). 077 * <p>If the invocation of {@code afterTestMethod()} throws an exception, that 078 * exception will also be tracked. Multiple exceptions will be combined into a 079 * {@link MultipleFailureException}. 080 */ 081 @Override 082 public void evaluate() throws Throwable { 083 Throwable testException = null; 084 List<Throwable> errors = new ArrayList<Throwable>(); 085 try { 086 this.next.evaluate(); 087 } 088 catch (Throwable ex) { 089 testException = ex; 090 errors.add(ex); 091 } 092 093 try { 094 this.testContextManager.afterTestMethod(this.testInstance, this.testMethod, testException); 095 } 096 catch (Throwable ex) { 097 errors.add(ex); 098 } 099 100 MultipleFailureException.assertEmpty(errors); 101 } 102 103}