0

クラスがあります。
そのクラスのコンストラクターで変数を初期化します。
ループを含むメソッドを呼び出し、while毎回変数をインクリメントします。
メソッドが呼び出された後(そしてwhileループを1回通過した後)に変数の値をチェックするテストを作成しました。

public class ThreadGenerator implements Runnable {
  private int requests;
  private int limit;

  public ThreadGenerator() {
    requests = 0;
  }

  public void setRequestLimit(int anyLimit) {
    this.limit = anyLimit;
  }

  public void generateThread() {
    new Thread(this).start();
  }

  public void run() {
      while(requests < limit) {
          try {
              // do some stuff
              requests++;
              // close some stuff
          } catch (IOException e) {
            e.printStackTrace();
          }
      }
  }

  public int getRequests() {
      return requests; // calling this method from my tests always returns 0
  }

私のテストでは、このクラスの新しいインスタンスを作成し、そのクラスでこのメソッドを呼び出すと、正しく実行され、リクエストカウンターが正しくインクリメントされます。私はそれを確認するためにいくつかのprintステートメントを試しました。しかし、テストでオブジェクトを呼び出すgetRequestsと、 ThreadGenerator初期化された量である0が返されます。

私のテストコード:

ThreadGenerator threadGenerator = new ThreadGenerator();
threadGenerator.setRequestLimit(1);
threadGenerator.generateThread();
assertEquals(threadGenerator.getRequests(), 1);

コンストラクターで初期化したこの変数を変更して、テストスイートでアクセスするにはどうすればよいですか?

4

2 に答える 2

5

run()Runnable を使用して新しいスレッドを作成するように Java に要求したからといって、そのメソッドがすぐに呼び出されるわけではないことに注意してください。初めて起こるassertEquals前に起こっている可能性があります。run

スレッドを返し、生成されたスレッドでテストを呼び出すことができjoinます。これにより、スレッドが終了するまで、おそらく短いタイムアウトで確実に実行されます。

/* in the system under test */
@VisibleForTesting Thread generateAndReturnThread() {
  Thread thread = new Thread(this);
  thread.start();
  return thread;
}

public void generateThread() {
  generateAndReturnThread();
}

/* in the test */
@Test public void yourTest() {
  ThreadGenerator threadGenerator = new ThreadGenerator();
  threadGenerator.setRequestLimit(1);

  // wait up to a second for thread to complete
  threadGenerator.generateThreadAndReturn().join(1000);

  assertEquals(threadGenerator.getRequests(), 1);
}

補足:AtomicInteger複数のスレッドが変更する可能性がある場合は、リクエスト クラスを考慮してくださいrequestsrequestsこれにより、2 つの異なるスレッドが互いを変更したり上書きしたりするのを防ぐことができます。

于 2013-01-10T06:17:33.527 に答える
1

上記の回答に加えて、別のスレッドが変数をインクリメントした後に実際に最新の値を取得できるように、変数を揮発性として宣言することを検討してください。

于 2013-01-10T06:47:03.433 に答える