3

コードの一部が無限の反復でスタックし、最終的にStackOverflowが発生するのを防ぐために、junitテストを作成しようとしています。

そのため、実行時にスタックサイズを減らして、Junittestがより速く失敗するようにする方法を探しています。

テストははるかに大きなテストスイートの一部であるため、最大スタックをjvm引数として設定することはできません。

4

4 に答える 4

5

再帰的なメソッドを実行して、それ自体を指定された回数実行してから、指定されたアクションを実行することができます。かなり不安定に聞こえますが:(

何かのようなもの:

public void eatStackThenExecute(int depth, Runnable action)
{
    // Maybe put some locals here (and use them) to eat more stack per iteration?
    if (depth == 0)
    {
        action();
    }
    else
    {
        eatStackThenExecute(depth - 1, action);
    }
}

編集:スマートJVMがここで末尾呼び出しを最適化する可能性があるため、再帰呼び出しの後に「何か」を実行して、それが起こらないようにする必要があるかもしれません...

Ick'n stuff :(

于 2009-06-11T11:02:55.907 に答える
2

実行時にスタック サイズを設定することはできませんが、おそらく次のことができます。

  • 別のスレッド内でそのコードを呼び出します-それへの参照を保持します。
  • 定期的にポーリングthread.getStackTrace()し、サイズが x より大きい場合は失敗します。
  • 実行が正しく終了した場合、チェックをキャンセルします。

コンパイルされていない概念実証コード (すべてのエッジ条件を適切にチェックするわけではありません):

AtomicBoolean success = new AtomicBoolean(false);

Thread t= new Thread(new Runnable() {
   public void run() {
       codeToTest();
       success.set(true);
   }

});

t.start();

while ( t.isAlive() ) {
     if ( t.getStackTrace().length > 50 )
          fail("Stack trace too large");

     Thread.sleep(50);
}

assertTrue(sucess.get());
于 2009-06-11T11:02:20.027 に答える
1

このようなパラメーターは起動時にしか設定できませんが、Java から別のプロセスを開始することはできます。そのため、単体テストでスタック サイズが小さい 2 番目のプロセスを開始して、テストを実行することができます。

于 2009-06-12T03:00:08.507 に答える