我有一个较大的代码库,包含许多装饰器类,它们通常将除一个方法外的所有方法委托给一个委托对象,例如:
class WrapperThing implements Thing{
private final Thing delegate;
WrapperThing(Thing thing){this.delegate=thing;}
public boolean method1(){ return delegate.method1(); }
public String method2(int arg1, boolean arg2){ return delegate.method2(arg1, arg2); }
// lots more methods here, all delegating to delegate
}
现在,我正在使用Junit 5@TestFactory
为这些包装创建单元测试,调用WrapperThing
上的每个方法,并希望验证包装委托上是否有调用,这是一个Mockito mock。
以下是我目前的代码:
private void testMethodDelegation(final Method method) {
D delegate = mock(delegateType);
W wrapper = createWrapper(delegate);
List<Object> args = new ArrayList<>(method.getParameterTypes().length + 1);
args.add(wrapper);
gatherMethodArgs(method, args); // populate args with mocks or default values
try {
method.invoke(args.toArray(new Object[0]));
}catch(Exception e) {
// this is fine, we're just testing the delegation
}
// now comes the verify part
List<Object> mockArgs = new ArrayList<>();
try {
mockArgs.add(verify(delegate));
mockArgs.addAll(nCopies(args.size()-1, any()));
method.invoke(mockArgs.toArray(new Object[0]));
}catch (Exception e) {
throw new IllegalStateException(e);
}
}
当我运行这个,我得到的错误是:
org.mockito.exceptions.misusing.InvalidUseOfMatchersException:
Misplaced or misused argument matcher detected here:
-> at some.packagename.AbstractDelegateTest.testMethodDelegation(AbstractDelegateTest.java:81)
You cannot use argument matchers outside of verification or stubbing.
Examples of correct usage of argument matchers:
when(mock.get(anyInt())).thenReturn(null);
doThrow(new RuntimeException()).when(mock).someVoidMethod(anyObject());
verify(mock).someMethod(contains("foo"))
我是否做错了什么,或者如果您不知道确切的方法,是否无法验证方法调用?
问题是我在调用方法。调用()错误。我认为格式是方法。调用([target,arg1,…argn])
,但它实际上是方法。调用(目标[arg1,…argn])
。这是漫长的一天,我的坏朋友。
此代码的工作原理:
private void testMethodDelegation(final Method method) {
D delegate = mock(delegateType);
W wrapper = createWrapper(delegate);
List<Object> args = new ArrayList<>(method.getParameterTypes().length);
gatherMethodArgs(method, args); // populate args with mocks or default values
try {
method.invoke(wrapper, args.toArray(new Object[0]));
} catch (Exception e) {
// this is fine, we're just testing the delegation
throw new IllegalStateException(e);
}
callVerify(method, delegate);
}
private void callVerify(final Method method, final D delegate) {
// now comes the verify part
List<Object> mockArgs = new ArrayList<>(method.getParameterTypes().length);
try {
D verifyDelegate = verify(delegate);
gatherVerifyArgs(method, mockArgs);
method.invoke(verifyDelegate, mockArgs.toArray(new Object[0]));
} catch (Exception e) {
throw new IllegalStateException(e);
}
}
private void gatherVerifyArgs(final Method method, final List<Object> args) {
for (Class<?> parameterType : method.getParameterTypes()) {
if (int.class == parameterType) {
args.add(anyInt());
} else if (boolean.class == parameterType) {
args.add(anyBoolean());
} else if (long.class == parameterType) {
args.add(anyLong());
} else if (double.class == parameterType) {
args.add(anyDouble());
} else if (float.class == parameterType) {
args.add(anyFloat());
} else if (String.class == parameterType) {
args.add(anyString());
} else {
args.add(any());
}
}
}
private void gatherMethodArgs(final Method method, final List<Object> args) {
int i = 0;
for (Class<?> type : method.getParameterTypes()) {
try {
if (type == String.class) {
args.add("");
} else if (type.isArray()) {
args.add(Array.newInstance(type.getComponentType(), 0));
} else if (Primitives.allPrimitiveTypes().contains(type)) {
args.add(Defaults.defaultValue(type));
} else if (Primitives.allWrapperTypes().contains(type)) {
args.add(Defaults.defaultValue(Primitives.unwrap(type)));
} else if (type == List.class) {
args.add(ImmutableList.of());
} else if (type == Set.class) {
args.add(ImmutableSet.of());
} else if (type == Map.class) {
args.add(ImmutableMap.of());
} else if (type.getName().startsWith("java.util.")) {
args.add(type.newInstance());
} else {
args.add(mock(type));
}
} catch (Exception e) {
throw new IllegalStateException(
String.format("Error mocking parameter %d (%s) of method %s", i,
method.getGenericParameterTypes()[i], method), e);
}
i++;
}
}
我找到了使用ReflectionUtils的方法 现在我想驱动这个方法返回一个指定的值。通常,如果< code>myMethod是公共的,我会写例如 但是有没有可能用私有的myMethod来实现呢?< br >当我打电话时 我有Java . lang . reflect . invocationtargetexception .我读过关于PowerMock的文章,但是我想知道是否只有Mockito
我对莫基托有疑问。我想测试这个简单的类: 我写了这个简单的测试: 此测试运行时没有错误。我等待它没有编译,因为没有任何对userService方法的调用…
Mockito似乎是一个非常好的Java存根/模拟框架。唯一的问题是我找不到任何关于使用API的最佳方法的具体文档。测试中使用的常用方法包括: 当您在实践中看到Mockito的示例时,您会看到如下代码: 从我读过的所有文档中,我已经识别了几个Mockito“语法”的“模式”,这些“语法”是通过将这些方法调用像上面的示例一样链接在一起而获得的。我发现的一些常见模式有: 当/然后:当(你的方法())。
Mockito——我知道间谍在对象上调用实际方法,而模拟在双对象上调用方法。此外,除非有代码气味,否则要避免间谍。然而,间谍是如何工作的?我应该在什么时候使用他们?它们与模拟有什么不同?
问题内容: 是否可以以编程方式在android中接听电话? 我找到了一些不可能的地方,但随后安装了应用https://play.google.com/store/apps/details?id=com.a0softus.autoanswer可以 正常工作。 我已经搜索了很多并尝试了很多方法,而且呼叫拒绝功能正常,但呼叫应答功能却无效。 我尝试了以下代码进行电话应答,如下所示: 函数拒绝调用可以正常
我正在尝试为具有特定扩展名的文件在“打开”菜单中添加eclipse编辑器。我在org.eclipse.ui.editors扩展点中使用launcher实现了这一点,在launcher中我使用了“open editor”方法,它需要传递编辑器ID。有没有什么方法可以让我们以编程方式打开一个编辑器,而不需要传递编辑器ID呢?我们可以通过传递实现编辑器的类的实例以编程方式打开编辑器吗?..