2

クラスにグローバル静的レジストリがあり、状況によってはインスタンスを登録します。実際にはガベージコレクションに依存していませんが、一部の機能は明らかにに配置されていfinalize()ます。

jUnitテスト中に、この機能がどのように機能するかをテストしたいのですが、GCを強制的に呼び出すことはできません。私は私を呼んgc()でいますtearDown()

@After
public void tearDown() throws Exception {

    log.debug("tearDown()");

    a = null;
    b = null;
    c = null;
    d = null;
    e = null;
    f = null;
    g = null;

    System.gc();

    log.debug("asserting hash size");
    assertEquals(0, Myclass.getRegisterSize());
}

しかし、これは役に立ちません。ファイナライズする前にアサートメッセージが表示されることがログに表示されます。

すべてのファイナライズが行われるまで待つことはできますか?

クラスローダーを再起動したり、ヒープをフラッシュしたり、jUnitで何かを実行したりするなど、他の手段はありますか?私はすべてをゼロから行うつもりですか?

4

5 に答える 5

2

ファイナライズをオーバーライドする場合は、直接呼び出すだけではどうでしょうか。現在、 finalizeは保護されていますが、サブクラスによって公開される可能性があります。次に、それを直接呼び出して、そこで何が呼び出されているかを確認できます。テストは決定論的である必要があるため、毎回実行する必要があります。ガベージコレクターに依存すると、何がいつ呼び出されるかを保証できないため、テストに不整合が生じる可能性があります。

于 2012-10-30T20:32:06.710 に答える
1

そうではなく、すべてのファイナライズが行われるのを待つことはできません。それらはまったく起こらないかもしれません。オブジェクトがガベージコレクションされると、Finalizeが実行されます。Mainクラスなど、一部のオブジェクトは収集されません。JVMはgc()を実行する前に終了するため、これはガベージコレクションを取得しません。

最良のアイデアは(実際には)クリーンアップを実行するメソッドを追加し、それをJUnitテストから呼び出すことです。そして、もしあなたが本当に本当に必要なら、finalize()からも。ただし、finalize()が呼び出されることに依存することはできません。

于 2012-10-30T20:28:36.973 に答える
0

テストを書くための最初のルールは、テスト可能なコードを書くことです。ファイナライズの効果を監視するテストをテスト設計できない限り、ファイナライズをテストするのは非常に困難です。

一般に、最終的に呼び出されることを信頼できるfinalize()ため、この機能を特にテストする必要はなく、代わりに、メソッドによって呼び出されるメソッドをテストする必要がありますfinalize()。それか、クラスを拡張して、テストコードがfinalize()メソッドによって変更されるオブジェクトを挿入できるようにします。

それか、finalize()テストコードから直接-methodを呼び出すだけです。

于 2012-10-30T20:35:01.483 に答える
0

JVMの「ファイナライズ」機能をテストしようとしているようですが、そうすべきではありません。ここで機能するのは、テストするコードを別のメソッドに移動し、通常どおり簡単な単体テストを作成することです。

于 2012-10-30T20:39:48.840 に答える
0

投稿されたコードから、アサーションを実行しているクラスではなく、junitテストのオブジェクトへの参照にnullを設定しています。したがって、MyClassには引き続きオブジェクトが参照されます。

于 2012-10-30T20:39:54.223 に答える