嘲笑うブロックの静的Java
-
09-06-2019 - |
質問
私のモットード"で、新しいパースペクティブの静的ブロックされているとは思いませんが、平均するのに使用します。" 冗談はさて多くの方々に支持してもらえればと思Javaる試験の悪夢です。最も忙しいは匿名クラスおよびStaticブロックとなります。多くのレガシーコードを用いた静的なブロックおよびこれらの迷惑にインクをプリンタに書きユニット。我々の目標を書くことができるユニットテストのための授業に依存しているこのstatic初期化最小限のコード変わります。
これまでの私の提案に同僚にとって身体の静的ブロックプライベートstaticメソッドを呼び出す staticInit
.このメソッドを呼び出すことができるの静的ブロックです。単体テストのために他のクラスに依存するこのクラスが容易に模擬 staticInit
とJMockitには何もしません。を見てみましょう、この一例です。
public class ClassWithStaticInit {
static {
System.out.println("static initializer.");
}
}
変更となります
public class ClassWithStaticInit {
static {
staticInit();
}
private static void staticInit() {
System.out.println("static initialized.");
}
}
こんに関する記述がありますJUnit.
public class DependentClassTest {
public static class MockClassWithStaticInit {
public static void staticInit() {
}
}
@BeforeClass
public static void setUpBeforeClass() {
Mockit.redefineMethods(ClassWithStaticInit.class, MockClassWithStaticInit.class);
}
}
しかしこのソリューションも付属する。きを走らせることができません DependentClassTest
や ClassWithStaticInitTest
同一のJVMのまったブロックの静的実行のため ClassWithStaticInitTest
.
うお遂行するタスク?又、非JMockitベースのソリューションというクリーナー?
解決
かにこの問題は、だいたい同じことについて説明していただけま以外に持ってもらうようにしてい静的な方法で保護されない呼び出しです。また、この方法で複数回呼び出されない問題なのではないが、静的な初期化子どを試験。
この作品を合理的にも、実際に試験する、静的初期化メソッドは何を期待してい/いすることができるようになります.ということもありだけで簡単に一部の静的初期化コードで名付けられたという価値で構築過度に複雑なシステムを交換してください。
ご利用する場合は、このメカニズムは、必ず文書の保護は、この露出試験目的で、こなれます。このコースにはならない場合があります可能な溶液に、例えばクラスのインターフェイスは、外部に見える(いずれかとして、成分の一部のような他のチームとしての公的枠組み).シンプルな問題の解決手段も必要としない第三者に図書館を設しました。
他のヒント
これは今より"先進"JMockit.ので、再定義静的初期化ブロックJMockitにより作成 public void $clinit()
方法。いえるのではなくこの変更
public class ClassWithStaticInit {
static {
staticInit();
}
private static void staticInit() {
System.out.println("static initialized.");
}
}
まなくてはならない休暇 ClassWithStaticInit
としては、以下の MockClassWithStaticInit
:
public static class MockClassWithStaticInit {
public void $clinit() {
}
}
このことによる変更を行えるようになり、既存のクラス.
時には、静initilizersの授業が自分のコードです。ただ、refactorのコードを使ってい PowerMock's @SuppressStaticInitializationFor
に対するアノテーションを抑制する静的な初期化子:
@RunWith(PowerMockRunner.class)
@SuppressStaticInitializationFor("com.example.ClassWithStaticInit")
public class ClassWithStaticInitTest {
ClassWithStaticInit tested;
@Before
public void setUp() {
tested = new ClassWithStaticInit();
}
@Test
public void testSuppressStaticInitializer() {
asserNotNull(tested);
}
// more tests...
}
について を抑制する不要な行動.
免責事項:PowerMockは、オープンソースプロジェクトが開発した二つの同僚の。
鳴っていくときに処理する症状:貧しいデザインの依存関係の静的初期化.もしかしたリファクタリングは実際の解決策です。そのようなまって少しリファクタリングをお staticInit()
機能も機能するニーズを呼び出すことができるコンストラクタはstatic初期化子.きく静initializersに当ります。みきのこの決定まcodebase が一部リファクタリングます。
と嘲笑うに使っているEasyMockが、今ではもうほとんど同じ問題です。副作用の静的initializersでレガシーコードを作試験は困難です。私たちの答えでしたrefactorのstatic初期化子.
きを書くテストコードGroovy、簡単に模擬、staticメソッドを使用metaprogramming.
Math.metaClass.'static'.max = { int a, int b ->
a + b
}
Math.max 1, 2
が使えない場合は、Groovy、本当に必要なリファクタリングのコードも入った子initializator).
種類について
思いったい何らかの工場では、static初期化子.
一部ミックスのシングルトンは、抽象的な工場だったろうことができるのと同様の機能は今日、いいtestabilityもうかなり多くのボイラープレートコードでは多めの方が良いでしょうかいrefactorの静的なものか全くやれば少なくとも離れても少な複雑な溶液とする。
難しい場合はその可能性を見ることなくコードになってる。
私はスーパーに精通模擬枠組みください正しい場合は私の間違いがない可能性もある二つの異なる擬似オブジェクトをカバーしない?など
public static class MockClassWithEmptyStaticInit {
public static void staticInit() {
}
}
や
public static class MockClassWithStaticInit {
public static void staticInit() {
System.out.println("static initialized.");
}
}
を利用することができれることにより体にやさしく、ほの異なるテストケース
@BeforeClass
public static void setUpBeforeClass() {
Mockit.redefineMethods(ClassWithStaticInit.class,
MockClassWithEmptyStaticInit.class);
}
や
@BeforeClass
public static void setUpBeforeClass() {
Mockit.redefineMethods(ClassWithStaticInit.class,
MockClassWithStaticInit.class);
}
ます。
な答えだ迷って-ない"逆転"に Mockit.redefineMethods
?
されていない場合は、明示的な方法が存在するのでなく、実行すると、次のファッションだという?
Mockit.redefineMethods(ClassWithStaticInit.class, ClassWithStaticInit.class);
場合このような方法が存在し、実行可能なので、クラス' @AfterClass
方法、および試験 ClassWithStaticInitTest
の"オリジナルの"static初期化子ブロックがまったく変わってはいないから、同じJVM.
とりあえず今回はそうな予感が、い合わせ下さい。