簡體   English   中英

調用參數上的方法時,PowerMockito模擬靜態方法失敗

[英]PowerMockito mocking static method fails when calling method on parameter

我正在嘗試測試一個使用帶有許多靜態方法的計算器類的類。 我以類似的方式成功地嘲笑了另一個班級,但是這個班級更加頑固。

似乎如果mocked方法在傳入的參數之一上包含方法調用,則靜態方法不會被模擬(並且測試中斷)。 刪除內部呼叫顯然不是一種選擇。 有什么明顯的東西我在這里不見了嗎?

這是一個濃縮版本,行為方式相同......

public class SmallCalculator {

    public static int getLength(String string){

        int length = 0;

        //length = string.length(); // Uncomment this line and the mocking no longer works... 

        return length;
    }
}

這是測試......

import static org.junit.Assert.assertEquals;
import static org.mockito.BDDMockito.given;
import static org.mockito.Matchers.any;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.powermock.api.mockito.PowerMockito;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;

import com.solveit.aps.transport.model.impl.SmallCalculator;

@RunWith(PowerMockRunner.class)
@PrepareForTest({ SmallCalculator.class})
public class SmallTester {

    @Test
    public void smallTest(){

        PowerMockito.spy(SmallCalculator.class);
        given(SmallCalculator.getLength(any(String.class))).willReturn(5);

        assertEquals(5, SmallCalculator.getLength(""));
    }
}

似乎對這個問題存在一些困惑,所以我設計了一個更“現實”的例子。 這個添加了一個間接級別,因此我似乎沒有直接測試模擬方法。 SmallCalculator類保持不變:

public class BigCalculator {

    public int getLength(){

        int length  = SmallCalculator.getLength("random string");

        // ... other logic

        return length;
    }

    public static void main(String... args){

        new BigCalculator();
    }
}

這是新的測試類......

import static org.junit.Assert.assertEquals;
import static org.mockito.BDDMockito.given;
import static org.mockito.Matchers.any;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.powermock.api.mockito.PowerMockito;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;

import com.solveit.aps.transport.model.impl.BigCalculator;
import com.solveit.aps.transport.model.impl.SmallCalculator;

@RunWith(PowerMockRunner.class)
@PrepareForTest({ SmallCalculator.class})
public class BigTester {

    @Test
    public void bigTest(){

        PowerMockito.spy(SmallCalculator.class);
        given(SmallCalculator.getLength(any(String.class))).willReturn(5);

        BigCalculator bigCalculator = new BigCalculator();
        assertEquals(5, bigCalculator.getLength());
    }
}

我在這里找到了答案https://blog.codecentric.de/en/2011/11/testing-and-mocking-of-static-methods-in-java/

這是最終的代碼。 我已經在原始代碼(以及人為的例子)中測試了這種方法,並且效果很好。 Simples ...

import static org.junit.Assert.assertEquals;
import static org.mockito.Matchers.any;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.powermock.api.mockito.PowerMockito;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;

@RunWith(PowerMockRunner.class)
@PrepareForTest({ SmallCalculator.class})
public class BigTester {

    @Test
    public void bigTest(){

        PowerMockito.mockStatic(SmallCalculator.class);
        PowerMockito.when(SmallCalculator.getLength(any(String.class))).thenReturn(5);

        BigCalculator bigCalculator = new BigCalculator();
        assertEquals(5, bigCalculator.getLength());
    }
}

使用anyString()而不是any(String.class)

當使用any(String.class) ,傳遞的參數為null ,因為Mockito將返回引用類型的默認值,即null 結果你得到一個例外。

使用anyString() ,傳遞的參數將為空字符串。

請注意,這解釋了為什么會出現異常,但是您需要檢查測試方法的方式,如其他注釋和答案中所述。

首先,刪除該行:

given(SmallCalculator.getLength(any(String.class))).willReturn(5);

因為您正在測試相同的方法。 您不想模擬您正在測試的方法。

其次,將注釋修改為:

@PrepareForTest({ SmallCalculator.class, String.class})

最后,為length()添加模擬; 像這樣:

given(String.length()).willReturn(5);

我認為它會做;)

如果您不希望調用實際方法。 代替

when(myMethodcall()).thenReturn(myResult);

使用

doReturn(myResult).when(myMethodCall());

這是嘲弄魔法,很難解釋為什么它真的有效。

你忘記的其他事情是mockStatic(SmallCalculator.class)

而且你不需要PowerMockito.spy(SmallCalculator.class);

暫無
暫無

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

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