簡體   English   中英

如何將 Mock 設置為具有默認行為並可以在某些測試中覆蓋它

[英]How to set Mock to have a default behavior and can override it in some test

我想在大多數測試用例中模擬一個依賴項並返回一個默認值,因為他們中的大多數人不應該關心返回的值,但是在某些特定情況下,我想測試依賴項返回一些奇怪的值或者只是拋出。 所以我以這種方式對其進行建模。 大多數情況下,它應該返回一個不錯且有效的值。

默認情況下為所有測試類返回20L的測試設置。

Dependency dependency = Mockito.mock(Dependency.class);
when(dependency.returnSomeVal()).thenReturn(20L);

在特定的測試用例 class 中,我想覆蓋如下行為:

when(dependency.returnSomeVal()).thenThrow(); //failure cases
when(dependency.returnSomeVal()).thenReturn(Weird_Val); //failure cases

但是我沒有找到一個很好的解決方案來覆蓋現有的行為? 任何想法?

您可以重置模擬並添加行為。 在測試中,做

Mockito.reset(dependency);
when(dependency.returnSomeVal()).thenThrow(); //failure cases
when(dependency.returnSomeVal()).thenReturn(Weird_Val); //failure cases

不過,重置將刪除此 class 上的所有模擬行為。 如果您只想重新模擬某些方法,那么您必須從頭開始創建模擬。

我結束了自己使用這種模式來模擬提供配置的 class 的一堆方法。

@Before方法中,我為模擬的 object 設置了一堆存根,為每個測試提供正確的配置。 之后,在每個測試中,僅覆蓋其中一個存根以提供不同的配置並測試不同的錯誤情況非常方便。

我認為 Hari Menon 的回答是正確的,但它在某種程度上違背了問題中解釋的目的。 如果重置了模擬,則需要再次添加所有存根,從而使這種模式非常混亂(在這種情況下,最好不要使用任何覆蓋而不是使用重置,代碼會更直接)。

添加到問題中的評論確實提供了關於如何實現這一點以及它為什么起作用的間接答案,但我花了一點時間才讓它起作用。

盡管有評論之一,我還是通過在我的 @Before 夾具中使用 when().thenReturn() 並用 doReturn().when() 覆蓋具體存根,使一切正常工作

例子:

public class WorkerTest {

    private ConfigProvider mockedConfigProvider = mock(ConfigProvider.class);

    @Before
    public void setup() {
    // Setup stubs with a correct config
        when(mockedConfigProvider.getValue("property1")).thenReturn("value1");
        when(mockedConfigProvider.getValue("property2")).thenReturn("value2");
        when(mockedConfigProvider.getValue("property3")).thenReturn("value3");
        when(mockedConfigProvider.getValue("property4")).thenReturn("value4");
    }

    @Test
    public void test_GoodConfig(){
        // The config object gets injected in the test worker
        Worker testWorker = new Worker(mockedConfigProvider);
        // testWorker.execute() returns true if everything went well
        assertTrue(testWorker.execute());
    }

    @Test
    public void test_BadConfigProp1(){
        // Test now with a broken 'property1', overriding that stub.
        doReturn(null).when(mockedConfigProvider).getValue("property1");
        Worker testWorker = new Worker(mockedConfigProvider);
        // testWorker.execute() returns false if there is a problem.
        assertFalse(testWorker.execute());
    }

    @Test
    public void test_BadConfigProp2(){
    // This test needs to only override the result of property2
    doReturn("crazy result").when(mockedConfigProvider).getValue("property2");
    ...

}

暫無
暫無

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

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