2016-09-20 6 views
0

私はJava 6とJunit 4.12を使用しています。スレッドがクラスから生成された場合、私はJUnitで検出しようとしています。私が試してみて、実行中のスレッドの一覧を取得するときに私のクラスでは、私は、私のJUnitテストでは、しかしそうスレッドがJUnitを使用して生成されたかどうかを検出するにはどうすればよいですか?

final Thread deletethirdpartyClassThread = new Thread(new Runnable(){ 
    @Override 
    public void run() 
    { 
     try { 
      Thread.sleep(1000); 
     } catch (InterruptedException e) { 
      LOG.error(e.getMessage(), e); 
     } 
     final String threadName = "deletethirdpartyClass:" + myId; 
     Thread.currentThread().setName(threadName); 
     m_thirdpartySvc.deleteObject(myId); 
    } 
}); 
deletethirdpartyClassThread.start(); 

のようなスレッドを生成、上記は現れません。ここでは、私は、スレッドの一覧を取得しようとしている方法です

boolean threadSpawned = false; 
final Set<Thread> threadSet = Thread.getAllStackTraces().keySet(); 
for (final Thread t : threadSet) { 
    if (StringUtils.equals(t.getName(), "deletethirdpartyClass:" + myId)) 
    { 
     threadSpawned = true; 
     break; 
    } // if 
} // for 

スレッドの一覧を表示するためのより良い方法はありますか生み出した私は、スレッドを検出することができます別の方法がありますか?

+2

あなたは、コンストラクタで名前を渡すことができます '新しいスレッド(実行可能、名)' – vsminkov

+0

私はいけない」udnerstandこれは、スレッドがアクティブであるなら、私は把握どのように役立ちますかか否か。 –

+1

スレッドを開始してその名前を割り当てるまでの遅延についての副次的なメモでした。 – vsminkov

答えて

0

あなたのクラスにThreadFactoryを注入し、代わりにThread::newを呼び出して、新しいスレッドを作成するためにそれを使用しています。 JUnitテストでは、カスタムThreadFactoryを簡単に挿入し、新しいThreadを作成するかどうかを確認することができます。

private final ThreadFactory threadFactory; 
private final Thread deletethirdpartyClassThread; 

public YourClass(ThreadFactory threadFactory) { 
    this.threadFactory = threadFactory; 
    deletethirdpartyClassThread = threadFactory.newThread(new Runnable(){ 
     @Override 
     public void run() 
     { 
      try { 
       Thread.sleep(1000); 
      } catch (InterruptedException e) { 
       LOG.error(e.getMessage(), e); 
      } 
      final String threadName = "deletethirdpartyClass:" + myId; 
      Thread.currentThread().setName(threadName); 
      m_thirdpartySvc.deleteObject(myId); 
     } 
    }); 
} 

およびカスタムThreadFactoryを巻か:

class MyThreadFactory implements ThreadFactory { 

    private AtomicInteger invocationCounter = new AtomicInteger(); 

    @Override 
    public Thread newThread(Runnable runnable) { 
     invocationCounter.incrementAndGet(); 
     return new Thread(runnable); 
    } 

    public int numberOfInvocations() { 
     return invocationCounter.get(); 
    } 
} 

あなたはMockitoを使用している場合、あなたは、単に代わりにspy()を使用することができます。試験で

あなたがこれを行うことができます。

public void test() { 

    MyThreadFactory threadFactory = new MyThreadFactory(); 
    YourClass yourClass = new YourClass(threadFactory); 

    yourClass. // invoke method under test 

    assertThat(threadFactory.numberOfInvocations()).isEqualTo(1); 

} 
+0

Java 6でこの機能を利用できますか? –

+0

これは特別な機能を使用していません、それは単なるプレーンですOO – bowmore

+0

いくつかのサンプルコードを追加しました – bowmore

0

これは過度に複雑に思えます。スレッドが実行を開始するときにスレッドにフラグを設定させ、ユニットテストでそのフラグがチェックされて設定されているかどうかを確認させます。例えば

、複数の「MYID」の値が可能であれば:、Boolean値が「myid」キーをマップするために使用されるパブリック静的HashMapを(私はs_threadFlagsそれを呼びます)を作成run()メソッドはそのを設定していますそのマップ内の "myId"値をBoolean.TRUEに設定し、ユニットテストクラスにそのキーの値を取得させます。

スレッドコードがあってもよい:

public static Map s_threadFlags; 
public static void clearThreadFlags() { s_threadFlags = null; }; 
public static void initThreadFlags() { s_threadFlags = new HashMap(); }; 

final Thread deletethirdpartyClassThread = new Thread(new Runnable(){ 
    @Override 
    public void run() 
    { 
     if (s_threadFlags != null) { 
      s_threadFlags.put(myId, Boolean.TRUE); 
     } 
     m_thirdpartySvc.deleteObject(myId); 
    } 
}); 
deletethirdpartyClassThread.start(); 

とユニットテストコードをに低減することができる:

  • MyThreadClass.initThreadFlags()への呼び出し:の添加により

    boolean threadSpawned = (MyThreadClass.s_threadFlags.get(myId) == Boolean.TRUE); 
    

    ユニットテストのBeforeメソッドまたはBeforeClassメソッド

  • AfterまたはAfterClassメソッドでMyThreadClass.clearThreadFlags()にコールしてクリーンアップします。
+0

解決策は、JUnitを満足させるためにテスト用のコードをコアJavaファイルに追加することです。私はそれをやりたいとは思わない。スレッドが生成されたかどうかを判断するために何らかの方法を使用することはできませんか? –

+0

スレッドが既に終了していても、スレッドが実行を開始したことを知るには、何らかの方法が必要です。現在のコード(@ vsminkovの提案された変更の後であっても、それが生きている限り適切なスレッドを検出することができます)は、もはや生きていないスレッドを検出しません。単体テストではなく、より完全で効率的なものになるように私の答えを更新しました。 – cybersam

+0

さらに、単体テストが進行中の場合にはおそらく2秒間スリープしているので、あなたはすでにスレッドクラスにユニットテスト関連のコードを持っているようです。プロダクションコードにこのような長い人為的な遅延があるのは、一般的には本当に悪い考えです。 – cybersam

関連する問題