2013-10-28 97 views
16

我使用PowerMock嘲笑在JUnit測試靜態方法,典型的做法如下:以編程方式替換PowerMock的@PrepareForTest?

@RunWith(PowerMockRunner.class) 
@PrepareForTest({Foo.class,Bar.class}) 
public class SomeUnitTest { 

    @Before 
    public void setUpTest() { 
    setUpFoo(); 
    setUpBar(); 
    } 

    private void setUpFoo() { 
    mockStatic(Foo.class); 
    when(Foo.someStaticMethod()).thenReturn(1); 
    } 

    private void setUpBar() { 
    mockStatic(Bar.class); 
    when(Bar.someStaticMethod()).thenReturn(2); 
    } 

    @Test 
    public void someTestCase() { 
    ... 
    } 

} 

這工作得很好,但我發現,指定@PrepareForTest註釋是阻止我做我的測試API靈活。

我希望做的是類似如下:

public class MockLibraryOne { 

    public static void setUpLibraryOne() { 
    setUpFoo(); 
    setUpBar(); 
    } 

    private static void setUpFoo() { 
    mockStatic(Foo.class); 
    when(Foo.someStaticMethod()).thenReturn(1); 
    } 

    private static void setUpBar() { 
    mockStatic(Bar.class); 
    when(Bar.someStaticMethod()).thenReturn(2); 
    } 

} 

@RunWith(PowerMockRunner.class) 
public class SomeUnitTest { 

    @Before 
    public void setUpTest() { 
    MockLibraryOne.setUpLibraryOne(); 
    } 

    @Test 
    public void someTestCase() { 
    ... 
    } 

} 

這裏我的單元測試對LibraryOne的依賴,但它不知道LibraryOne取決於哪些類,所以它不知道將哪些類添加到@PrepareForTest註釋中。

我可以讓SomeUnitTest延長MockLibraryOne@PrepareForTest註釋添加到MockLibraryOne類,但我會對不僅僅是MockLibraryOne在其他單元測試更依賴,所以繼承不是一個通用的解決方案。

是否有某種編程方式爲PowerMock下的測試準備類,而不是使用@PrepareForTest註釋?例如,像下面這樣:

public class MockLibraryOne { 

    public static void setUpLibraryOne() { 
    setUpFoo(); 
    setUpBar(); 
    } 

    private static void setUpFoo() { 
    prepareForTest(Foo.class); 
    mockStatic(Foo.class); 
    when(Foo.someStaticMethod()).thenReturn(1); 
    } 

    private static void setUpBar() { 
    prepareForTest(Bar.class); 
    mockStatic(Bar.class); 
    when(Bar.someStaticMethod()).thenReturn(2); 
    } 

} 

我想這將是很好,如果PowerMockRunner處理@PrepareForTest註釋的方式有點不同:對於每個指定的類,它不應該只添加類(和它的層次)到類列表爲嘲諷準備,但然後檢查類,看它是否有任何@PrepareForTest註釋以及:

@RunWith(PowerMockRunner.class) 
@PrepareForTest({MockLibraryOne.class}) 
public class SomeUnitTest { 
    ... 
} 

@PrepareForTest({Foo.class,Bar.class}) 
public class MockLibraryOne { 
    ... 
} 

}

所以在這個@PrepareForTest annotatio n在SomeUnitTest將會發現MockLibraryOne,並且@PrepareForTest註釋將在Foo.classBar.class中拖拽。

所以也許寫我自己的測試跑步者替換PowerMockRunner可能是一個解決方案。

或者有更簡單的解決方案,例如使用PowerMockAgent類?

編輯:模擬策略可能是一個解決辦法:https://code.google.com/p/powermock/wiki/MockPolicies

編輯:模擬策略可與PowerMockRunner但不(似乎)與PowerMockRule(我有時由於類加載器問題需要)。

+0

我正面臨同樣的問題。你有沒有找到解決辦法? – Madhujith

+0

你知道你可以使用每個方法的@PrepareForTest註解來代替每個類嗎? – spekdrum

回答

0

也許您正在尋找mock policy

+0

感謝您的回覆。我研究了'MockPolicy',但正如我上面提到的,它只能用於'PowerMockRunner'而不是'PowerMockRule'。由於類加載器問題,我需要使用'PowerMockRule','MockPolicy'初始化程序只能與'PowerMockRunner'提供的'MockClassLoader'一起使用。 –

1

爲什麼你甚至想嘲笑靜態方法?爲什麼不把這些靜態方法包裝在可以用mockito模擬的類中?

class FooWraper { 
    void someMethod() { 
    Foo.someStaticMethod() 
    } 
} 

然後你可以爲你的FooWraper創建一個模擬。根本不需要使用Powermock ...

相關問題