[英]How to mock static method without powermock
在 JUnit 中進行測試時,有什么方法可以模擬靜態 util 方法?
我知道 Powermock 可以模擬靜態調用,但我不想使用 Powermock。
有沒有其他選擇?
(不過我假設你可以使用 Mockito)我沒有想到專門的東西,但是當涉及到這樣的情況時,我傾向於使用以下策略:
1)在被測類中,將靜態直接調用替換為對封裝靜態調用本身的包級方法的調用:
public class ToBeTested{
public void myMethodToTest(){
...
String s = makeStaticWrappedCall();
...
}
String makeStaticWrappedCall(){
return Util.staticMethodCall();
}
}
2)在測試的同時監視被測類並模擬包裝的包級別方法:
public class ToBeTestedTest{
@Spy
ToBeTested tbTestedSpy = new ToBeTested();
@Before
public void init(){
MockitoAnnotations.initMocks(this);
}
@Test
public void myMethodToTestTest() throws Exception{
// Arrange
doReturn("Expected String").when(tbTestedSpy).makeStaticWrappedCall();
// Act
tbTestedSpy.myMethodToTest();
}
}
這是我寫的一篇關於間諜的文章,其中包括類似的案例,如果您需要更多的洞察力: sourceartists.com/mockito-spying
當你的靜態代碼給你的單元測試帶來麻煩時; 所以你覺得你必須“嘲笑它”,你有這些選擇:
換句話說:如果您想使用模擬框架,則必須使用上面列出的框架之一。 一方面,這絕對是公平的。 靜態是 Java 語言的一部分; 那么為什么不使用允許您處理它的框架呢?
但是當然:那時您的生產代碼中仍然有靜態調用。 導致緊耦合,防止多態。
所以:如果你能擺脫靜態調用(即使只是使用另一個答案中建議的解決方法) - 那就更好了。 如果不是:Mockito 無能為力; 你需要字節碼操作的魔力。 JVM 代理。
您可以使用Mockito
(自3.4.0版起)來模擬靜態方法。
給定一個類Foo
:
class Foo{
static String method() {
return "foo";
}
}
這是測試:
@Test
void testMethod() {
assertEquals("foo", Foo.method());
try (MockedStatic mocked = Mockito.mockStatic(Foo.class)) {
mocked.when(Foo::method).thenReturn("bar");
assertEquals("bar", Foo.method());
mocked.verify(Foo::method);
}
assertEquals("foo", Foo.method());
}
這需要依賴org.mockito:mockito-inline:3.4.0
或更新版本。
我很幸運地做了一些類似於 Maciej 在上面的回答中建議的事情。 在 Java8 中,我喜歡用函數式接口包裝這些靜態方法,使它們更容易注入或模擬。 例如:
public class MyClass {
private MyStaticWrapper staticWrapper;
public MyClass(final MyStaticWrapper staticWrapper) {
this.staticWrapper = staticWrapper;
}
public void main() {
...
staticWrapper.doSomething();
...
}
}
public interface MyStaticWrapper {
default void doSomething() {
Util.annoyingUntestableStaticFunction();
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.