簡體   English   中英

Mockito無效使用匹配器Mock(Object.class)和anyString()

[英]Mockito Invalid use of matchers Mock(Object.class) & anyString()

好啦

我正忙着寫一個單元測試

 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和隨機的String調用monitor.severe時,event.fire調用中的“級別”參數將填充正確的值。

首先,一些基本知識:

  • 模擬是可以使用模擬框架創建的真實對象的替代。 它記錄其交互並驗證它們以供以后使用。
  • 諸如anyanyStringeq類的匹配器會告訴您的模擬框架(不是您的測試框架或被測系統)哪種類型的調用與存根 (告訴模擬在其方法被調用時如何表現)或驗證 (詢問您的模擬)有關模擬框架(無論是否調用了某種方法)。

最重要的是,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的信號,一個真正的實現正在處理它,而不是Mockito。

/*  OK */ monitor.severe(mock(MonitorEventType.class), "");

您正在為實際的被測系統提供模擬的實現和真實的字符串,因此這是Mockito的正確用法,即使它沒有表達您要測試的內容。


除了使用Mockito之外,真正的問題是您想在測試中引入隨機性 即使Mockito是完成這項工作的正確工具(肯定不是),那么根據選擇的輸入,測試可能會通過90%的時間而失敗10%的時間。 這將使您的測試充其量只能是嘈雜的/片狀的,甚至可能導致您的團隊普遍忽略測試的價值。

相反,選擇具有代表性的用例或邊緣用例 如果您有enum-type參數,則還可以遍歷所有值並為每個值運行一次測試。 您可能不需要Mockito,除非出於某種原因無法輕松創建MonitorEventType實例。 那么您可能會使用Mockito創建偽造的MonitorEventType來與您的真實Monitor進行交互。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM