001// Copyright 2007, 2011, 2012 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.EasyMock;
018import org.easymock.IMocksControl;
019
020/**
021 * Contains core logic used by {@link TestBase}, allowing for mock objects to be used outside of a TestNG-based test
022 * suite. A <em>single</em> standard mock control is used for all mock instances. The control does not care about
023 * execution order, but will balk at any unexpected method invocations. This class is thread safe (it used a thread
024 * local to store the mock control).
025 * <p>
026 * This class was originally in the tapestry-ioc module as was moved to tapestry-test; the package name was not changed
027 * to ensure backwards compatibility.
028 * @deprecated In 5.4, with no replacement
029 */
030public final class MockTester
031{
032    private static class ThreadLocalControl extends ThreadLocal<IMocksControl>
033    {
034        @Override
035        protected IMocksControl initialValue()
036        {
037            return EasyMock.createControl();
038        }
039    }
040
041    private final ThreadLocalControl localControl = new ThreadLocalControl();
042
043    /**
044     * Invoked after an individual unit test (i.e., a test method invocation) to discard the mock control.
045     */
046    public synchronized void cleanup()
047    {
048        localControl.remove();
049    }
050
051    public synchronized IMocksControl getMocksControl()
052    {
053        return localControl.get();
054    }
055
056    /**
057     * Creates a new mock object of the indicated type. The shared mock control does <strong>not</strong> check order,
058     * but does fail on any unexpected method invocations.
059     * 
060     * @param <T>
061     *            the type of the mock object
062     * @param mockClass
063     *            the class to mock
064     * @return the mock object, ready for training
065     */
066    public <T> T newMock(Class<T> mockClass)
067    {
068        return getMocksControl().createMock(mockClass.getSimpleName(), mockClass);
069    }
070
071    /**
072     * Switches each mock object created by {@link #newMock(Class)} into replay mode (out of the initial training
073     * mode).
074     */
075    public void replay()
076    {
077        getMocksControl().replay();
078    }
079
080    /**
081     * Verifies that all trained methods have been invoked on all mock objects (created by {@link #newMock(Class)}, then
082     * switches each mock object back to training mode.
083     */
084    public void verify()
085    {
086        IMocksControl control = getMocksControl();
087
088        control.verify();
089        control.reset();
090    }
091}