解決 Mockito 異常:需要但未調用
一、概述
在本教程中,我們將討論使用 Mockito 時可能遇到的常見錯誤。 Exception消息是:
Wanted but not invoked:
// class name and location
Actually, there were zero interactions with this mock.
讓我們了解此錯誤的潛在來源以及如何修復它。
2. 示例設置
首先,讓我們創建我們稍後要模擬的類。它包含一個單獨的方法,它總是返回String , “Baeldung” :
class Helper {
String getBaeldungString() {
return "Baeldung";
}
}
現在讓我們創建我們的主類。它在類級別聲明一個Helper實例。我們想在單元測試期間模擬這個實例:
class Main {
Helper helper = new Helper();
String methodUnderTest(int i) {
if (i > 5) {
return helper.getBaeldungString();
}
return "Hello";
}
}
最重要的是,我們定義了一個接受Integer作為參數並返回的方法:
- 如果
Integer大於 5,調用getBaeldunString()的結果 - 如果
Integer小於或等於 5,則為常量
3.調用真正的方法而不是模擬
讓我們嘗試為我們的方法編寫單元測試。我們將使用@Mock註釋來創建模擬的Helper 。我們還將調用MockitoAnnotations.openMocks()來啟用 Mockito 註釋。在測試方法中,我們將使用參數7調用methodUnderTest()並檢查它是否委託給getBaeldungString() :
class MainUnitTest {
@Mock
Helper helper;
Main main = new Main();
@BeforeEach
void setUp() {
MockitoAnnotations.openMocks(this);
}
@Test
void givenValueUpperThan5_WhenMethodUnderTest_ThenDelegatesToHelperClass() {
main.methodUnderTest(7);
Mockito.verify(helper)
.getBaeldungString();
}
}
現在讓我們運行我們的測試:
Wanted but not invoked:
helper.getBaeldungString();
-> at com.baeldung.wantedbutnotinvocked.Helper.getBaeldungString(Helper.java:6)
Actually, there were zero interactions with this mock.
問題是我們調用了構造函數來實例化一個Main對象。因此, Helper實例是通過調用new()創建的。因此,我們使用真正的Helper對象而不是我們的模擬對象。要解決這個問題,我們需要在我們的Main對象創建之上添加@InjectMocks :
@InjectMocks
Main main = new Main();
作為旁注,如果我們在methodUnderTest()的任何點用真實對象替換模擬實例,我們將再次陷入同樣的問題:
String methodUnderTest(int i) {
helper = new Helper();
if (i > 5) {
return helper.getBaeldungString();
}
return "Hello";
}
簡而言之,我們這裡有兩個注意點:
- 應該正確創建和注入模擬。
- 在任何時候都不應將模擬對象替換為其他對象。
4.方法未被調用
我們現在將編寫一個新的單元測試。它將檢查將3作為參數傳遞給methodUnderTest()是否會調用getBaeldungString() :
@Test
void givenValueLowerThan5_WhenMethodUnderTest_ThenDelegatesToGetBaeldungString() {
main.methodUnderTest(3);
Mockito.verify(helper)
.getBaeldungString();
}
再一次,我們可以運行測試:
Wanted but not invoked:
helper.getBaeldungString();
-> at com.baeldung.wantedbutnotinvocked.Helper.getBaeldungString(Helper.java:6)
Actually, there were zero interactions with this mock.
這次,讓我們仔細閱讀錯誤信息。它說我們沒有與模擬交互。現在讓我們回顧一下我們的方法規範: 3小於5 ,因此methodUnderTest()返回一個常量而不是委託給getBaeldungString() 。因此,我們的測試與規範相矛盾。
在這種情況下,我們只有兩種可能的結論:
- 規範是正確的:我們需要修復我們的測試,因為驗證是無用的。
- 測試是正確的:我們的代碼中有一個錯誤需要解決。
5.結論
在本文中,我們在沒有與模擬交互的情況下調用Mockito.verify()並出現錯誤。我們指出我們需要正確地註入和使用模擬。我們還看到這個錯誤是在不連貫的測試中出現的。
與往常一樣,代碼在 GitHub 上可用。