13
12

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

jUnit で非同期処理のテストがちょっと楽になるクラス作ってみた

Last updated at Posted at 2012-12-26

非同期メソッドのテストって、皆さんどうやってるんでしょう?
ちょっとググってみたけど「Object.wait とか CountDownLatch とか Future で待て」とかあんまり良い答えが見つからなかったので、自分でユーティリティクラス作ってみた。

まあ CountDownLatch で待ってるだけなんですけども。

2013.1.10 修正:メソッドに全部 synchronized つけたら動かんやん、恥ずかし…

FutureResult.java
/**
 * success または error が呼ばれるまで get() で待ってる Future みたいなクラス
 * 
 * @author @amay077
 */
public class FutureResult<T> {
	private final int TIMEOUT = 10;
	private final TimeUnit TIMEOUT_UNIT = TimeUnit.SECONDS;
	
	private final CountDownLatch _latch = new CountDownLatch(1);
	private T _value;
	private Exception _error;

	public static class FutureResultException extends Exception {
		private static final long serialVersionUID = 1L;

		public FutureResultException(Exception detailException) {
			super(detailException);
		}
	}
	
	/**
	 * 非同期処理が成功したら呼ぶメソッド
	 */
	public synchronized void success(T value) {
		_value = value;
		_latch.countDown();
	}

	/**
	 * 非同期処理が失敗したら呼ぶメソッド
	 */
	public synchronized void error(Exception ex) {
		_error = ex;
		_latch.countDown();
	}

	/**
	 * 非同期処理が終わるまで待って結果を返す。
	 * エラーだったら例外を投げる。
	 */
	public T get() throws Exception {
		try {
			if (!_latch.await(TIMEOUT, TIMEOUT_UNIT)) {
				throw new FutureResultException(new TimeoutException());
			}
		} catch (Exception ex) {
			throw new FutureResultException(ex);
		}
		
		if (_error != null) {
			throw _error;
		}
		
		return _value;
	}

}

Future インターフェースを implements しようと思ったけど数が多くてやめたw
使い方はこんな感じ。

AsyncMethodTest.java
public void testAsyncMethod() {
	final FutureResult<Integer> result = new FutureResult<Integer>();
	
	// 非同期なメソッドを実行
	hoge.asyncMethod(new OnReceiveListener() {
		@Override
		public void onReceive(Integer data) {
			// 正そうな値を受信しtら success を呼ぶ
			result.success(data);
		}
		
		@Override
		public void onError(Exception ex) {
			// エラーを受信した場合は error を呼ぶ
			result.error(ex);
		}
	});
	
	// 検証
	try {
		// get で success か error かタイムアウトするまで待ってる。
		Assert.assertEquals(0, result.get()); 
	} catch (Exception e) {
		fail(e.getMessage());
	}
}

参考

なんて記事を書いたあとにもっかいググってみたらこんなライブラリがあるようで。詳細はまだ見てない。

  • Awaitility - Awaitility is a small Java-based DSL for synchronizing asynchronous operations. It makes it easy to test asynchronous code. - Google Project Hosting
13
12
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
13
12

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?