2013-10-28 11 views
16

私は次のように一般的に行われ、JUnitテストの静的メソッドを模擬するためにPowerMockを使用しています: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アノテーションに追加するかを指定します。

私はSomeUnitTestMockLibraryOneを拡張し、MockLibraryOneクラスに@PrepareForTest注釈を追加する作ることができますが、私はちょうどMockLibraryOne他のユニットテストよりも上の依存関係を持つことになりますので、継承は、一般的なソリューションではありません。

@PrepareForTest注釈を使用する代わりに、プログラムでPowerMockでのテスト用のクラスを準備する方法はありますか?たとえば、次のようなもの:に指定された各クラスに対して、それだけでそのクラス(およびその階層)を追加しないでください:PowerMockRunnerは少し違っ@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); 
    } 

} 

モックの準備をするクラスのリストが、それは同様に任意の@PrepareForTest注釈を持っているかどうかを確認するために、そのクラスを調べます。この中のSO

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

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

}

@PrepareForTest annotatioをSomeUnitTest上のnはMockLibraryOneとなり、とBar.classには@PrepareForTest注釈が含まれています。

おそらくPowerMockRunnerの代わりに私自身のテストランナーを書くことが解決策になるかもしれません。

たとえば、クラスを使用すると、単純な解決策がありますか?

編集:モックポリシーは1つの解決策になることがあります。https://code.google.com/p/powermock/wiki/MockPolicies

編集:モックポリシー(私は時々、クラスローダの問題のために必要)PowerMockRuleで(それはそう)PowerMockRunnerで動作しますが、ありません。

+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をまったく使用する必要はありません...