org.test4j.mock.faking.meta.FakeInvocation Maven / Gradle / Ivy
package org.test4j.mock.faking.meta;
import lombok.Getter;
import lombok.Setter;
import org.test4j.mock.Invocation;
import org.test4j.mock.faking.util.ReflectUtility;
import java.lang.reflect.Constructor;
import java.lang.reflect.Executable;
import java.lang.reflect.Member;
import java.lang.reflect.Method;
import static org.test4j.mock.faking.modifier.BridgeFakeInvocation.Enter_Non_Mock_Block;
/**
* Invocation实现
*
* @author darui.wu
*/
@SuppressWarnings({"unused", "unchecked"})
public class FakeInvocation extends Invocation {
/**
* 被Mock(被调用)的实例对象
*/
@Getter
private final Object target;
private final FakeMethod fakeMethod;
/**
* real object实现方法: method, Constructor
*/
private final Executable invokedMember;
/**
* 方法参数
*/
@Getter
private final Object[] args;
/**
* {@link FakeMethod#getTimesInvoked()}快照值
*/
@Getter
private final int invokedTimes;
/**
* true: 进入doFake()过程
* false: 进入method real implement
* invocation.proceed(...)需要设置成false, 以进入method real implement
*/
@Getter
@Setter
private boolean proceeding;
public FakeInvocation(Object target, Object[] args, FakeMethod fakeMethod, Executable invokedMember) {
this.target = target;
this.args = args;
this.fakeMethod = fakeMethod;
this.invokedTimes = fakeMethod.getTimesInvoked();
this.invokedMember = invokedMember;
}
public final T proceed(Object... args) {
fakeMethod.setProceedingInvocation(this);
proceeding = true;
if (this.invokedMember instanceof Constructor) {
return (T) Enter_Non_Mock_Block;
}
try {
Object[] actualArgs = args != null && args.length > 0 ? args : this.args;
return ReflectUtility.invoke(this.target, (Method) this.invokedMember, actualArgs);
} finally {
fakeMethod.clearProceedIndicator();
}
}
/**
* 是否是构造函数中调用 inv.process()方法
*
* @return ignore
*/
public boolean isProceedIntoConstructor() {
if (proceeding && invokedMember instanceof Constructor) {
fakeMethod.clearProceedIndicator();
return true;
} else {
return false;
}
}
/**
* 设置Invocation.proceeding = true, 避免循环
*
* @param invocation Invocation
*/
public static void prepareToProceedNonRecursiveMock(Invocation invocation) {
((FakeInvocation) invocation).fakeMethod.setProceedingInvocation4NonRecursive(invocation);
}
/**
* 返回实际执行方法(或构造函数, 静态代码块)
*
* @param type
* @return ignore
*/
public M getInvokedMember() {
return (M) this.invokedMember;
}
}