奥拉,
我正在忙于编写像
这样的单元测试 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));
}
我想要的是当我使用随机的MonitorEventType和随机字符串调用monitor.severe时,&#34; level&#34;参数在teh event.fire中填充了正确的值。
答案 0 :(得分:2)
首先,一些基础知识:
any
,anyString
或eq
这样的匹配器会告诉您的模拟框架(不是您的测试框架或您测试的系统)什么样的调用与 stubbing 相关(告诉你的mock在调用方法时如何表现)或验证(询问你的模拟框架是否调用某个方法)。最重要的是,JUnit和Mockito不允许使用&#34;对任何输入进行测试&#34;:any
之类的语句只存在,所以当我收到任何参数时你可以说&#34; ,采取这个行动&#34;或者&#34;检查是否使用任何参数调用方法&#34;。
现在你的例子:
/* 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的信号,真正的实现正在处理这个,而不是Mockito。
/* OK */ monitor.severe(mock(MonitorEventType.class), "");
您正在为您的真实系统提供模拟实现和真实字符串,因此这是对Mockito的正确使用,即使它没有表达您想要测试的内容。 / p>
除了使用Mockito之外,这里真正的问题是你想在你的测试中引入 randomness 。即使Mockito是工作的正确工具 - 它绝对不是 - 然后你的测试可能会在90%的时间内通过,并且在10%的时间内失败,具体取决于选择的输入。这将使您的测试充其量嘈杂/片状,甚至可能导致您的团队忽略测试的价值。
相反,选择代表用例或边缘情况;如果您有一个枚举类型参数,您还可以迭代所有值并按值运行一次测试。你可能不需要Mockito,除非你出于某种原因不能轻易创建一个MonitorEventType实例;那么你可以使用Mockito创建一个假的MonitorEventType来与你正在测试的真实Monitor进行交互。