001    // Copyright 2006, 2007, 2008, 2010, 2011 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    
015    package org.apache.tapestry5.ioc.test;
016    
017    import org.easymock.Capture;
018    import org.easymock.EasyMock;
019    import org.easymock.IAnswer;
020    import org.easymock.IExpectationSetters;
021    import org.easymock.IMocksControl;
022    import org.testng.annotations.AfterMethod;
023    
024    /**
025     * Manages a set of EasyMock mock objects. Used as a base class for test cases.
026     * <p/>
027     * Extends from {@link org.testng.Assert} to bring in all the public static assert methods without requiring extra
028     * imports.
029     * <p/>
030     * Provides a common mock factory method, {@link #newMock(Class)}. A single <em>standard</em> mock control is used for
031     * all mock objects. Standard mocks do not care about the exact order in which methods are invoked, though they are as
032     * rigorous as strict mocks when checking that parameters are the correct values.
033     * <p/>
034     * This base class is created with the intention of use within a TestNG test suite; if using JUnit, you can get the same
035     * functionality using {@link MockTester}.
036     * <p/>
037     * This class is thread safe (it uses a thread local to store the mock control). In theory, this should allow TestNG to
038     * execute tests in parallel.
039     * <p>
040     * This class was originally in the tapestry-ioc module as was moved to tapestry-test; the package name was not changed
041     * to ensure backwards compatibility.
042     * 
043     * @see org.easymock.EasyMock#createControl()
044     * @see org.apache.tapestry5.ioc.test.MockTester
045     */
046    public class TestBase extends TestUtils
047    {
048        private final MockTester tester = new MockTester();
049    
050        /**
051         * @return the {@link IMocksControl} for this thread.
052         */
053        protected final IMocksControl getMocksControl()
054        {
055            return tester.getMocksControl();
056        }
057    
058        /**
059         * Discards any mock objects created during the test.
060         */
061        @AfterMethod(alwaysRun = true)
062        public final void discardMockControl()
063        {
064            tester.cleanup();
065        }
066    
067        /**
068         * Creates a new mock object of the indicated type. The shared mock control does <strong>not</strong> check order,
069         * but does fail on any unexpected method invocations.
070         * 
071         * @param <T>
072         *            the type of the mock object
073         * @param mockClass
074         *            the class to mock
075         * @return the mock object, ready for training
076         */
077        protected final <T> T newMock(Class<T> mockClass)
078        {
079            return tester.newMock(mockClass);
080        }
081    
082        /**
083         * Switches each mock object created by {@link #newMock(Class)} into replay mode (out of the initial training
084         * mode).
085         */
086        protected final void replay()
087        {
088            tester.replay();
089        }
090    
091        /**
092         * Verifies that all trained methods have been invoked on all mock objects (created by {@link #newMock(Class)}, then
093         * switches each mock object back to training mode.
094         */
095        protected final void verify()
096        {
097            tester.verify();
098        }
099    
100        /**
101         * Convienience for {@link EasyMock#expectLastCall()} with {@link IExpectationSetters#andThrow(Throwable)}.
102         * 
103         * @param throwable
104         *            the exception to be thrown by the most recent method call on any mock
105         */
106        protected static void setThrowable(Throwable throwable)
107        {
108            EasyMock.expectLastCall().andThrow(throwable);
109        }
110    
111        /**
112         * Convienience for {@link EasyMock#expectLastCall()} with
113         * {@link IExpectationSetters#andAnswer(org.easymock.IAnswer)}.
114         * 
115         * @param answer
116         *            callback for the most recent method invocation
117         */
118        protected static void setAnswer(IAnswer<?> answer)
119        {
120            EasyMock.expectLastCall().andAnswer(answer);
121        }
122    
123        /**
124         * Convenience for {@link EasyMock#expect(Object)}.
125         * 
126         * @param value to expect
127         * @return expectation setter, for setting return value, etc.
128         */
129        @SuppressWarnings("unchecked")
130        protected static <T> IExpectationSetters<T> expect(T value)
131        {
132            return EasyMock.expect(value);
133        }
134    
135        /**
136         * A factory method to create EasyMock Capture objects.
137         * @return new Capture
138         */
139        @SuppressWarnings({"UnusedDeclaration"})
140        protected static <T> Capture<T> newCapture()
141        {
142            return new Capture<T>();
143        }
144    }