使用 Mockito 註釋

我們要測試的類是:

public class Service{

    private Collaborator collaborator;

    public Service(Collaborator collaborator){
        this.collaborator = collaborator;
    }
    
    
    public String performService(String input){
        return collaborator.transformString(input);
    }
}

它的合作者是:

public class Collaborator {

    public String transformString(String input){
        return doStuff();
    }

    private String doStuff()
    {
        // This method may be full of bugs
        . . .
        return someString;
    }

}

在我們的測試中,我們希望打破 Collaborator 及其錯誤的依賴性,因此我們將模擬 Collaborator。使用 @Mock 註釋是為每個測試建立不同模擬例項的便捷方法:

import static org.junit.Assert.*;
import static org.mockito.Mockito.*;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.InjectMocks;
import org.mockito.runners.MockitoJUnitRunner;

@RunWith(MockitoJUnitRunner.class)
public class ServiceTest {

    @Mock
    private Collaborator collaboratorMock;

    @InjectMocks
    private Service service;
    
    @Test
    public void testPerformService() throws Exception {
        // Configure mock
        doReturn("output").when(collaboratorMock).transformString("input");            

        // Perform the test
        String actual = service.performService("input");
        
        // Junit asserts
        String expected = "output";
        assertEquals(expected, actual);
    }
    
    
    @Test(expected=Exception.class)
    public void testPerformServiceShouldFail() throws Exception {
        // Configure mock
        doThrow(new Exception()).when(collaboratorMock).transformString("input");

        // Perform the test
        service.performService("input");
    }
}

Mockito 將嘗試按以下順序解決依賴注入:

  1. 基於建構函式的注入 - 使用大多數引數將模擬注入到建構函式中(如果找不到某些引數,則傳遞空值)。如果通過建構函式成功建立了物件,則不會應用其他策略。
  2. 基於定位器的注入 - 模擬按型別注入。如果存在多個相同型別的屬性,則將匹配屬性名稱和模擬名稱。
  3. 直接進樣 - 與基於 setter 的進樣相同。

請注意,如果上述任何策略失敗,則不會報告失敗。

有關 Mockito 最新版本中此機制的更多詳細資訊,請參閱最新的 @InjectMocks