001/* 002 * Copyright (C) 2008 The Guava Authors 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); you may not 005 * use this file except in compliance with the License. You may obtain a copy 006 * of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 012 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 013 * License for the specific language governing permissions and limitations under 014 * the License. 015 */ 016 017package com.google.common.util.concurrent.testing; 018 019import static com.google.common.util.concurrent.MoreExecutors.directExecutor; 020import static java.util.concurrent.TimeUnit.SECONDS; 021import static org.junit.Assert.assertThrows; 022 023import com.google.common.annotations.GwtIncompatible; 024import com.google.common.util.concurrent.ListenableFuture; 025import java.util.concurrent.CountDownLatch; 026import java.util.concurrent.ExecutionException; 027import junit.framework.Assert; 028 029/** 030 * A simple mock implementation of {@code Runnable} that can be used for testing ListenableFutures. 031 * 032 * @author Nishant Thakkar 033 * @since 10.0 034 */ 035@GwtIncompatible 036public class MockFutureListener implements Runnable { 037 private final CountDownLatch countDownLatch; 038 private final ListenableFuture<?> future; 039 040 public MockFutureListener(ListenableFuture<?> future) { 041 this.countDownLatch = new CountDownLatch(1); 042 this.future = future; 043 044 future.addListener(this, directExecutor()); 045 } 046 047 @Override 048 public void run() { 049 countDownLatch.countDown(); 050 } 051 052 /** 053 * Verify that the listener completes in a reasonable amount of time, and Asserts that the future 054 * returns the expected data. 055 * 056 * @throws Throwable if the listener isn't called or if it resulted in a throwable or if the 057 * result doesn't match the expected value. 058 */ 059 public void assertSuccess(Object expectedData) throws Throwable { 060 // Verify that the listener executed in a reasonable amount of time. 061 Assert.assertTrue(countDownLatch.await(1L, SECONDS)); 062 063 try { 064 Assert.assertEquals(expectedData, future.get()); 065 } catch (ExecutionException e) { 066 throw e.getCause(); 067 } 068 } 069 070 /** 071 * Verify that the listener completes in a reasonable amount of time, and Asserts that the future 072 * throws an {@code ExecutableException} and that the cause of the {@code ExecutableException} is 073 * {@code expectedCause}. 074 */ 075 public void assertException(Throwable expectedCause) throws Exception { 076 // Verify that the listener executed in a reasonable amount of time. 077 Assert.assertTrue(countDownLatch.await(1L, SECONDS)); 078 079 ExecutionException expected = assertThrows(ExecutionException.class, () -> future.get()); 080 Assert.assertSame(expectedCause, expected.getCause()); 081 } 082 083 public void assertTimeout() throws Exception { 084 // Verify that the listener does not get called in a reasonable amount of 085 // time. 086 Assert.assertFalse(countDownLatch.await(1L, SECONDS)); 087 } 088}