簡體   English   中英

使用 Guice,如何將單元測試中的模擬對象注入正在測試的類中

[英]Using Guice, how do I inject a mock object from my unit test, into the class being tested

考慮以下代碼:

@Singleton
public class MyServiceImpl {
    public int doSomething() {
        return 5;
    }
}

@ImplementedBy(MyServiceImpl.class)
public interface MyService {
    public int doSomething();
}

public class MyCommand {
    @Inject private MyService service;

    public boolean executeSomething() {
        return service.doSomething() > 0;
    }
}

public class MyCommandTest {
    @InjectMocks MyServiceImpl serviceMock;
    private MyCommand command;

    @Before public void beforeEach() {
        MockitoAnnotations.initMocks(this);
        command = new MyCommand();
        when(serviceMock.doSomething()).thenReturn(-1); // <- Error here
    }

    @Test public void mockInjected() {
        boolean result = command.executeSomething();
        verify(serviceMock).doSomething();
        assertThat(result, equalTo(false));
    }
}

當我嘗試在模擬實現對象上存根 doSomething() 方法時,我的測試失敗了。 我收到錯誤:

org.mockito.exceptions.misusing.MissingMethodInvocationException: when() 需要一個必須是“模擬方法調用”的參數。 例如:when(mock.getArticles()).thenReturn(articles);

此外,出現此錯誤的原因可能是: 1. 您存根了以下任一方法: final/private/equals()/hashCode() 方法。 這些方法不能被存根/驗證。 不支持在非公共父類上聲明的模擬方法。 2. 在 when() 中,您不會在模擬上調用方法,而是在其他對象上調用方法。

我是通過 Guice 進行依賴注入的新手,不知道為什么我不能以這種方式模擬實現對象?

沒有 CDI 的測試

一個簡單的解決方案是將 CDI 與構造函數注入結合起來,而無需考慮 Guice 進行測試:

public class MyCommand {
    private final MyService service;

    @Inject
    public MyCommand(MyService service) {
        this.service = service;
    }

    public boolean executeSomething() {
        return service.doSomething() > 0;
    }
}

@RunWith(MockitoJUnitRunner.class)
public class MyCommandTest {
    @Mock
    MyServiceImpl serviceMock;
    private MyCommand command;

    @Before public void beforeEach() {
        MockitoAnnotations.initMocks(this);
        when(serviceMock.doSomething()).thenReturn(-1); // <- Error here

        // inject without Guice
        command = new MyCommand(serviceMock);
    }
}

用 Mockito 做 CDI 測試

否則,如果您不喜歡構造函數注入,則測試代碼應如下所示:

@RunWith(MockitoJUnitRunner.class)
public class MyCommandTest {
    @Mock
    MyServiceImpl serviceMock;
    @InjectMocks 
    private MyCommand command;

    @Before 
    public void beforeEach() {
        MockitoAnnotations.initMocks(this);
        command = new MyCommand();
        when(serviceMock.doSomething()).thenReturn(-1); // <- Error here
    }
}

暫無
暫無

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

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