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
015package org.apache.tapestry5.ioc.test;
016
017import org.easymock.Capture;
018import org.easymock.EasyMock;
019import org.easymock.IAnswer;
020import org.easymock.IExpectationSetters;
021import org.easymock.IMocksControl;
022import 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 */
046public 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}