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

org.test4j.mock.faking.fluent.MockMethod Maven / Gradle / Ivy

package org.test4j.mock.faking.fluent;

import org.test4j.mock.Invocation;
import org.test4j.mock.faking.meta.MethodId;

import java.util.concurrent.atomic.AtomicInteger;
import java.util.function.BiConsumer;
import java.util.function.Consumer;

/**
 * 自定义mock行为
 *
 * @author darui.wu
 */
@SuppressWarnings({"rawtypes", "unused", "unchecked"})
public class MockMethod {
    protected final FluentMockUp mockUp;

    private final String realClass;

    private final String name;

    private final String desc;

    private final AtomicInteger index = new AtomicInteger(0);

    public MockMethod(FluentMockUp mockUp, String realClass, String name, String desc) {
        this.mockUp = mockUp;
        this.realClass = realClass;
        this.name = name;
        this.desc = desc;
    }

    /**
     * 对方法参数校验
     * 
     *     .assertResult(inv -> {})
     * 
* * @param asserts Invocation Consumer * @return MockMethod */ public MockMethod assertParameters(Consumer asserts) { String methodDesc = MethodId.buildMethodDesc(this.name, this.desc); this.mockUp.addAssertMethodParas(methodDesc, asserts); this.placeHolder(); return this; } /** * 对真实调用结果进行断言 *
     *     .assertResult((inv,rst) -> {})
     * 
* * @param asserts Invocation Consumer * @return ignore */ public MockMethod assertResult(BiConsumer asserts) { String methodDesc = MethodId.buildMethodDesc(this.name, this.desc); this.mockUp.addAssertMethodResult(methodDesc, asserts); this.placeHolder(); return this; } /** * mock调用依次返回的结果值 * * @param values return value list * @return ignore */ public MockMethod thenReturn(R... values) { if (values == null) { values = (R[]) new Object[]{null}; } for (Object value : values) { int times = index.incrementAndGet(); this.mockUp.mockReturn(this.realClass, this.name, this.desc, times, value); } this.mockUp.apply(); return this; } /** * 指定时序结果 * * @param times 方法调用时序列表, 从1开始计数 * @param values return value list * @return ignore */ public MockMethod thenReturn(int[] times, R... values) { if (times == null) { return this.thenReturn((R[]) nullPlusArray(values)); } int max = 0; if (values == null) { values = (R[]) new Object[]{null}; } for (int index = 0; index < times.length; index++) { R value = this.getValue(values, index); this.mockUp.mockReturn(this.realClass, this.name, this.desc, times[index], value); max = Math.max(max, times[index]); } this.setIncreaseTimes(max); this.mockUp.apply(); return this; } private Object[] nullPlusArray(Object[] array) { Object[] objects = new Object[array == null ? 2 : array.length + 1]; objects[0] = null; if (array == null) { objects[1] = null; } else { System.arraycopy(array, 0, objects, 1, array.length); } return objects; } /** * 除已指定的行为外, 剩下的调用都返回value * * @param value return value */ public void restReturn(R value) { this.mockUp.mockReturn(this.realClass, this.name, this.desc, INDEX_REST_BEHAVIOR, value); this.mockUp.apply(); } /** * mock调用依次抛出异常 * * @param es throw exception * @return ignore */ public MockMethod thenThrows(Throwable... es) { if (es == null) { es = new Throwable[]{null}; } for (Throwable e : es) { this.mockUp.mockThrows(this.realClass, this.name, this.desc, index.incrementAndGet(), e); } this.mockUp.apply(); return this; } public MockMethod thenThrows(int[] times, Throwable... es) { if (times == null) { return this.thenThrows((Throwable[]) nullPlusArray(es)); } int max = 0; if (es == null) { es = new Throwable[]{null}; } for (int index = 0; index < times.length; index++) { Throwable e = this.getValue(es, index); this.mockUp.mockThrows(this.realClass, this.name, this.desc, times[index], e); max = Math.max(max, times[index]); } this.setIncreaseTimes(max); this.mockUp.apply(); return this; } /** * 除已指定的行为外, 剩下的调用都抛出异常 * * @param e throw exception */ public void restThrows(Throwable e) { this.mockUp.mockThrows(this.realClass, this.name, this.desc, INDEX_REST_BEHAVIOR, e); this.mockUp.apply(); } /** * 按序执行模拟逻辑 * * @param fake fake function * @return ignore */ public MockMethod thenAnswer(FakeFunction fake) { if (fake == null) { throw new RuntimeException("The parameter[fake] of restAnswer method can't be null."); } this.mockUp.mockMethod(this.realClass, this.name, this.desc, index.incrementAndGet(), fake); this.mockUp.apply(); return this; } /** * mock调用依次执行的逻辑 * * @param timeSeq 从1开始计数 * @param fake fake function * @return ignore */ public MockMethod thenAnswer(int timeSeq, FakeFunction fake) { if (fake == null) { throw new RuntimeException("The parameter[fake] of restAnswer method can't be null."); } return this.thenAnswer(new int[]{timeSeq}, fake); } /** * mock调用依次执行的逻辑 * * @param times 指定时序, 从1开始计数 * @param fake fake function * @return ignore */ public MockMethod thenAnswer(int[] times, FakeFunction fake) { if (fake == null) { throw new RuntimeException("The parameter[fake] of restAnswer method can't be null."); } int max = 0; for (int time : times) { this.mockUp.mockMethod(this.realClass, this.name, this.desc, time, fake); max = Math.max(max, time); } this.setIncreaseTimes(max); this.mockUp.apply(); return this; } /** * 除已指定的行为外, 剩下的调用执行的逻辑 * * @param fake fake function */ public void restAnswer(FakeFunction fake) { if (fake == null) { throw new RuntimeException("The parameter[fake] of restAnswer method can't be null."); } this.mockUp.mockMethod(this.realClass, this.name, this.desc, INDEX_REST_BEHAVIOR, fake); this.mockUp.apply(); } /** * 默认行为序号 */ public final static int INDEX_REST_BEHAVIOR = 0; private A getValue(A[] values, int index) { if (values == null) { return null; } int size = values.length; if (size == 0) { return null; } else { return index < size ? values[index] : values[size - 1]; } } /** * 按指定时序设置过, 把自增序列设置到最大值 */ private void setIncreaseTimes(int max) { if (this.index.get() < max) { this.index.set(max); } } /** * 占位处理, 保证在没有设置模拟行为, 只设置了{@link #assertParameters(Consumer)} 和 {@link #assertResult(BiConsumer)} * 时, {@link org.test4j.mock.faking.meta.FakeStates#getLastMethod(MethodId)}可以找到断言 */ private void placeHolder() { this.mockUp.mockReturn(this.realClass, this.name, this.desc, -1, null); this.mockUp.apply(); } /** * 清空行为时, 定义序号归零 */ public void resetIndex() { this.index.set(0); } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy