1

JUnit テストを作成しようとしています。私の問題は、コードのシーケンシャル ビット (スレッドを開始する前のコード) で作成したオブジェクトをスレッドが認識できないことです。

public class MyTest implements Runnable {

    private MyClass mc;

    /**
     * @throws InterruptedException
     */
    @Test
    public void parallelTest() throws InterruptedException {
        this.mc = new MyClass();
        Thread thread1 = new Thread(new MyTest());
        Thread thread2 = new Thread(new MyTest());
        thread1.join();
        thread2.join();
        thread1.start();
        thread2.start();
        // TODO the test
    }

    public void run() {
       if(mc != null) {
          System.out.println("ph not null");
       } else {
          System.out.println("ph null"); // THIS CODE GETS EXECUTED
       }
       // some code
    }
}

run上記のメソッドのコメントを参照してください。私のオブジェクトは null ですが、両方のスレッドがMyClassオブジェクトにアクセスできるようにしたいと考えています。なぜ彼らはヌルを見るのですか?コンストラクターを使用してみましたが、インターフェースが原因でパラメーターをコンストラクターに渡すことができなかったと思います。

どうもありがとう。

4

3 に答える 3

5

実行可能な各インスタンスは、 を使用して作成されますnew MyTest()。MyTest クラスには、フィールドを初期化するコンストラクターがありませんprivate MyClass mc;。そのため、デフォルト値は null です。

各オブジェクトには、独自のインスタンス フィールドがあります。それが OO の基本原則です。

于 2013-07-20T16:51:37.850 に答える
0

.mcのフィールドを初期化しますが、 (は初期化されていません。つまり、 です)thisの 2 つの新しいインスタンスを作成し、これらのインスタンスをスレッドに渡します。MyTest.mcnull

したがって、解決策は非常に簡単ですthis。スレッドに渡します。

[編集]

また、.start() 呼び出しと .join() 呼び出しの順序を入れ替える必要がありました。スレッドが終了するのを待つこと (つまり、join) は、スレッドが以前に開始されている場合にのみ意味があります。

package p1;

import org.junit.Test;

public class MyTest implements Runnable {

  private MyClass mc;

  /**
   * @throws InterruptedException
   */
  @Test
  public void parallelTest() throws InterruptedException {
      this.mc = new MyClass();
      Thread thread1 = new Thread(this);
      Thread thread2 = new Thread(this);
      thread1.start();
      thread2.start();
      thread1.join();
      thread2.join();
  }

  public void run() {
     if(mc != null) {
        System.out.println("ph not null");
     } else {
        System.out.println("ph null"); // THIS CODE GETS EXECUTED
     }
     // some code
  }
}

実行すると、次の出力が得られます。

ph not null
ph not null
于 2013-07-20T17:18:45.470 に答える
0

私はそれを解決しました:)。私が抱えていたいくつかのさらなる問題があったので、私はいくつかの+1を与えます:

  1. @ジェフリー:はい、startそしてjoin間違った方法でした
  2. @JB Nizet:ありがとう..質問にクレイジーなタイプミスがありました(編集された質問)

@Itay Maman は私と同じ考えを持っていましたが、うまくいきませんでした.JUnit では、コンストラクターにパラメーターを渡すことができませんでした。

解決策は、コンストラクターを使用するのではなく、 @BeforeClass アノテーションとinitメソッドを使用してMyClass.

public class MyTest implements Runnable {

    private static MyClass mc;

    @BeforeClass
    public static void init() {
        mc = new MyClass();
    }

    @Test
    public void parallelTest() throws InterruptedException {
        Thread thread1 = new Thread(new MyTest());
        Thread thread2 = new Thread(new MyTest());
        thread1.start();
        thread2.start();
        thread1.join();
        thread2.join();
        // my assertion about mc object goes here
    }

    public void run() {
        // code to test
    }
}

この単体テストでは、実行パスが非決定論的であるため、コードを完全にテストしていないため、合格することもあれば失敗することもあります。おそらく、より細かいテストも追加する予定です。

于 2013-07-20T18:59:07.463 に答える