gpt4 book ai didi

java - 使用 Mockito 时是否可以为所有答案添加拦截器?

转载 作者:塔克拉玛干 更新时间:2023-11-03 05:29:31 27 4
gpt4 key购买 nike

假设我在我的接口(interface)方法上有一个验证注释来验证输入参数和返回值。目前(V 1.9.5)是否可以告诉 Mockito 在调用过程中调用此 validator ?

背景是防止开发人员通过以违反指定 validator 的方式模拟给定接口(interface)来编写不切实际的测试。

所以我想要的是注册类似的东西

class MyAnswerInterceptor<T> implements AnswerInterceptor<T> {
@Override
public Answer<T> intercept(final Answer<T> answer) {
return new Answer<T>() {
@Override
public T answer(InvocationOnMock invocation) throws Throwable {
validateArguments(invocation);
T result = answer.answer(invocation);
validateReturnValue(result);
return result;
}
}
}
}

在给定模拟的每个答案上调用。这可能吗?我查看了代码,也检查了我是否可以在某个时候入侵(甚至使用反射等),但似乎由于实例创建和逻辑的纠缠,几乎不可能实现我想要的(即像 MockHandler mockHandler = new MockHandlerFactory().create(settings); 这样的东西使得在不修补和部署整个东西的情况下无法 Hook 并将自定义的东西放在上面......)

任何见解将不胜感激:-)

最佳答案

您可以通过创建自定义 MockMaker 来实现.

MockMaker is an extension point that makes it possible to use custom dynamic proxies and avoid using the default cglib/asm/objenesis implementation

我们的自定义实现将所有复杂的东西委托(delegate)给默认的 MockMaker:CglibMockMaker。它只“装饰” createMock通过在 settings 参数上注册一个 InvocationListener 的方法.当 invocation 完成允许调用 validateArgumentsvalidateReturnValue 时,此监听器将收到通知。

import org.mockito.internal.creation.CglibMockMaker;
import org.mockito.invocation.Invocation;
import org.mockito.invocation.MockHandler;
import org.mockito.listeners.InvocationListener;
import org.mockito.listeners.MethodInvocationReport;
import org.mockito.mock.MockCreationSettings;
import org.mockito.plugins.MockMaker;

public class ValidationMockMaker implements MockMaker {
private final MockMaker delegate = new CglibMockMaker();

public ValidationMockMaker() {
}
@Override
public <T> T createMock(MockCreationSettings<T> settings, MockHandler handler) {
settings.getInvocationListeners().add(new InvocationListener() {

@Override
public void reportInvocation(MethodInvocationReport methodInvocationReport) {
Invocation invocation = (Invocation) methodInvocationReport.getInvocation();
validateArguments(invocation.getArguments());
validateReturnValue(methodInvocationReport.getReturnedValue());
}
});
return delegate.createMock(settings, handler);
}

@Override
public MockHandler getHandler(Object mock) {
return delegate.getHandler(mock);
}

@Override
public void resetMock(Object mock, MockHandler newHandler, MockCreationSettings settings) {
delegate.resetMock(mock, newHandler, settings);
}

protected void validateArguments(Object... arguments) {
// Arrays.stream(arguments).forEach(Objects::requireNonNull);
}

private void validateReturnValue(Object result) {
// Objects.requireNonNull(result);
}
}

最后但同样重要的是,我们需要告诉 Mockito 使用我们的实现。这可以通过添加一个文件来实现

mockito-extensions/org.mockito.plugins.MockMaker 

包含我们的 MockMaker 类名:

ValidationMockMaker

参见 Using the extension point javadoc 中的部分。

关于java - 使用 Mockito 时是否可以为所有答案添加拦截器?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17389563/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com