ola,
我正在忙着写一个单位测试,例如
monitor.severe(mock(MonitorEventType.class), anyString());
当我执行此操作时,我会得到:
Invalid use of argument matchers.
0 matchers expected, 1 recorded.
所以我尝试了:
monitor.severe(mock(MonitorEventType.class), eq(anyString()));
但这给了
Invalid use of argument matchers.
0 matchers expected, 2 recorded.
我也尝试使用
monitor.severe(any(MonitorEventType.class), anyString());
,但这给出了一个无效的指针。
有效的是
monitor.severe(mock(MonitorEventType.class), "");
但这不是我想要的。
我的testMethod是:
@Test
public void testSevere() {
monitor.severe(mock(MonitorEventType.class), eq(anyString()));
ArgumentCaptor<DefaultMonitoringEventImpl> captor = ArgumentCaptor.forClass(DefaultMonitoringEventImpl.class);
verify(event).fire(captor.capture());
DefaultMonitoringEventImpl input = captor.getValue();
assertThat(fetchMonitorLevel(input), equalTo(MonitorEventLevel.SEVERE.getDescription()));
}
private String fetchMonitorLevel(DefaultMonitoringEventImpl input) {
Map<String, String> map = input.getMonitorEventWaardes().getWaardenLijst();
return map.get(MonitorEvent.MONITOR_EVENT_LEVEL_KEY);
}
,正在测试的方法是:
public void severe(MonitorEventType type, String message) {
write(type, MonitorEventLevel.SEVERE, message, null);
}
@Asynchronous
public void write(MonitorEventType type, MonitorEventLevel level, String message, MonitorEventWaardes pEventWaardes) {
event.fire(new DefaultMonitoringEventImpl(type, level, message, pEventWaardes));
}
我想要的是,当我致电Monitor.severe时,带有随机的monitoreventType和一个随机字符串,该字符串是teh event.fire呼叫中的"级别"参数的随机字符串。
首先,一些基础:
- a 模拟是替代真实对象,您可以使用模拟框架创建。它记录其互动并验证它们以后。
- A Matcher 喜欢
any
,anyString
或eq
告诉您的模拟框架(不是您的测试框架或正在测试的系统),哪种呼叫与 stubbing (告诉您的模拟如何在调用方法时表现)或验证(询问您的模拟框架是否称为某个方法)。
最重要的是,Junit和Mockito不允许诸如"对任何输入进行测试"之类的语句:仅存在any
之类的语句用任何参数调用"。
现在您的示例:
/* BAD */ monitor.severe(mock(MonitorEventType.class), anyString());
这是不起作用的,因为monitor
是真实的,因此anyString
不合适。不过,您的模拟在那里很好,因为您正在提供模拟实现来测试真实实现。
/* BAD */ monitor.severe(mock(MonitorEventType.class), eq(anyString()));
这是与上述相同的问题,但是双重的问题:eq
应该具有真正的价值,从不像anyString
这样的匹配器。
/* BAD */ monitor.severe(any(MonitorEventType.class), anyString());
在这里,您已将两个匹配项提供给真实的方法调用。匹配器只是摩擦着的信号,而真正的实现正在处理此问题,而不是Mockito。
/* OK */ monitor.severe(mock(MonitorEventType.class), "");
您正在向您的实际系统中的实际系统提供模拟实现和真实的字符串,因此这是对Mockito的适当使用,即使它没有表达您要测试的内容。
除了使用Mockito之外,这里的真正问题是您要将随机性引入测试。即使Mockito是工作的正确工具(绝对不是),因此您的测试可能会在90%的时间内通过,而在10%的时间内取决于选择的输入。这充其量会使您的测试嘈杂/片状,甚至可能导致您的团队一般测试的价值。
相反,选择代表性用例或边缘案例;如果您具有枚举类型参数,则还可以在所有值中迭代并每次值一次测试。您可能不需要Mockito,除非您由于某种原因无法轻易创建MonitoreVentType实例。然后,您可能会使用Mockito创建一个假的MonitoreVentType,以与您正在测试的真实显示器进行交互。