All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.powermock.api.mockito.internal.expectation.DelegatingToConstructorsOngoingStubbing Maven / Gradle / Ivy

/*
 * Copyright 2012 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.powermock.api.mockito.internal.expectation;

import org.mockito.ArgumentMatchers;
import org.mockito.stubbing.Answer;
import org.mockito.stubbing.OngoingStubbing;
import org.powermock.core.spi.support.InvocationSubstitute;

import java.lang.reflect.Constructor;

import static org.mockito.Mockito.when;

/**
 * Implementation of OngoingStubbing that delegates invocations to all supplied ctors
 * @param 
 */
public class DelegatingToConstructorsOngoingStubbing implements OngoingStubbing{

    private final OngoingStubbing stubbing;
    private final Constructor[] ctors;

    public DelegatingToConstructorsOngoingStubbing(Constructor[] ctors, OngoingStubbing stubbing) {
        if(stubbing == null) {
            throw new IllegalArgumentException("Internal error: Ongoing stubbing must be provided");
        }
        this.ctors = ctors;
        this.stubbing = stubbing;
    }

    @Override
    public OngoingStubbing thenReturn(final T value) {
        stubbing.thenReturn(value);
        return new InvokeStubMethod() {
            @Override
            public void performStubbing(OngoingStubbing when) {
                when.thenReturn(value);
            }
        }.invoke();
    }

    @Override
    public OngoingStubbing thenReturn(final T value, final T... values) {
        stubbing.thenReturn(value, values);
        return new InvokeStubMethod() {
            @Override
            public void performStubbing(OngoingStubbing when) {
                when.thenReturn(value, values);
            }
        }.invoke();
    }

    @Override
    public OngoingStubbing thenThrow(final Throwable... throwables) {
        stubbing.thenThrow(throwables);
        return new InvokeStubMethod() {
            @Override
            public void performStubbing(OngoingStubbing when) {
                when.thenThrow(throwables);
            }
        }.invoke();
    }
    
    @Override
    public OngoingStubbing thenThrow(final Class throwableType) {
        stubbing.thenThrow(throwableType);
        return new InvokeStubMethod() {
            @Override
            public void performStubbing(OngoingStubbing when) {
                when.thenThrow(throwableType);
            }
        }.invoke();
    }
 
    @Override
    public OngoingStubbing thenThrow(final Class toBeThrown, final Class[] nextToBeThrown) {
        stubbing.thenThrow(toBeThrown, nextToBeThrown);
        return new InvokeStubMethod() {
            @Override
            public void performStubbing(OngoingStubbing when) {
                when.thenThrow(toBeThrown, nextToBeThrown);
            }
        }.invoke();
    }

    @Override
    public OngoingStubbing thenCallRealMethod() {
        stubbing.thenCallRealMethod();
        return new InvokeStubMethod() {
            @Override
            public void performStubbing(OngoingStubbing when) {
                when.thenCallRealMethod();
            }
        }.invoke();
    }

    @Override
    public OngoingStubbing thenAnswer(final Answer answer) {
        stubbing.thenAnswer(answer);
        return new InvokeStubMethod() {
            @Override
            public void performStubbing(OngoingStubbing when) {
                when.thenAnswer(answer);
            }
        }.invoke();
    }

    @Override
    public OngoingStubbing then(final Answer answer) {
        stubbing.then(answer);
        return new InvokeStubMethod() {
            @Override
            public void performStubbing(OngoingStubbing when) {
                when.then(answer);
            }
        }.invoke();
    }

    @Override
    public  M getMock() {
        return stubbing.getMock();
    }


    private abstract class InvokeStubMethod {
        public OngoingStubbing invoke() {
            final InvocationSubstitute mock = stubbing.getMock();
            for (Constructor constructor : ctors) {
                final Class[] parameterTypesForCtor = constructor.getParameterTypes();
                Object[] paramArgs = new Object[parameterTypesForCtor.length];
                for (int i = 0; i < parameterTypesForCtor.length; i++) {
                    Class paramType = parameterTypesForCtor[i];
                    paramArgs[i] = ArgumentMatchers.nullable(paramType);
                }
                try {
                    final OngoingStubbing when = when(mock.performSubstitutionLogic(paramArgs));
                    performStubbing(when);
                } catch (Exception e) {
                    throw new RuntimeException("PowerMock internal error",e);
                }
            }

            return stubbing;
        }

        public abstract void performStubbing(OngoingStubbing when);

    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy