001/*
002 * Copyright 2015 SirWellington Tech.
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 *      http://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 tech.sirwellington.alchemy.test.mockito;
018
019import org.mockito.stubbing.Answer;
020import tech.sirwellington.alchemy.annotations.access.NonInstantiable;
021import static tech.sirwellington.alchemy.test.Checks.Internal.checkThat;
022
023/**
024 * This class contains a variety of useful answers for use in combination with Mockito.
025 *
026 * @author SirWellington
027 */
028@NonInstantiable
029public final class MoreAnswers
030{
031
032    MoreAnswers() throws IllegalAccessException
033    {
034        throw new IllegalAccessException("cannot instantiate class");
035    }
036    
037    
038    /**
039     * For example:
040     *
041     * <pre>
042     *
043     * {@code
044     * when(object.call("firstArg", 3)).then(returnFirst());
045     * }
046     * Will return the {@code "firstArg"} string when it is called.
047     * </pre>
048     *
049     * @param <T>
050     *
051     * @return
052     *
053     * @see #returnArgumentAtIndex(int)
054     */
055    public static <T> Answer<T> returnFirst()
056    {
057        return returnArgumentAtIndex(0);
058    }
059
060    /**
061     * An answer that returns one of the parameters as the return value.
062     *
063     * Example:
064     * <pre>
065     * when(someMock.call(anyString(), anyString()).then(returnArgumentAtIndex(1));
066     *
067     * String result = someMock.call("arg1", "arg2");
068     * assertThat(result, is("arg2"));
069     * </pre>
070     *
071     * @param <T>
072     * @param index zero-based index which determines which parameter to return as an answer.
073     *
074     * @return
075     *
076     * @see #returnFirst()
077     */
078    public static <T> Answer<T> returnArgumentAtIndex(int index)
079    {
080        checkThat(index >= 0, "Index is out of bounds.");
081        return (i) ->
082        {
083            if (index >= i.getArguments().length)
084            {
085                throw new IllegalArgumentException("Received an index of " + index + " but only " + i.getArguments().length + " arguments");
086            }
087            return (T) i.getArguments()[index];
088        };
089    }
090}