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();
}
}
staticがある場合、ユニットテストで問題が発生します。 「あざける」必要があると感じるように、次のオプションがあります。
つまり、モックフレームワークを使用する場合は、上記のいずれかを使用する必要があります。一方では、それは絶対に公平です。 staticは、Java言語の一部です。したがって、それを処理できるフレームワークを使用してみませんか?
しかし、もちろん、あなたはまだ実動コードでstatic呼び出しを持っています。密結合につながり、多型を防ぎます。
そのため、static呼び出しを削除できる場合(他の回答で提案されている回避策を使用する場合でも)-さらに良いことです。そうでない場合:Mockitoは役に立ちません。バイトコード操作の魔法が必要です。 JVMエージェント。
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();
}
}