/**
* Copyright (c) 2014 - 2017 Frank Appel
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Frank Appel - initial API and implementation
*/
package com.codeaffine.util.concurrent;
import static com.codeaffine.test.util.lang.ThrowableCaptor.thrownBy;
import static org.junit.Assert.assertSame;
import static org.mockito.Mockito.doThrow;
import static org.mockito.Mockito.inOrder;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
import java.util.concurrent.locks.Lock;
import java.util.function.Supplier;
import org.junit.Before;
import org.junit.Test;
import org.mockito.InOrder;
public class SynchronizerTest {
private Synchronizer synchronizer;
private Lock lock;
@Before
public void setUp() {
lock = mock( Lock.class );
synchronizer = new Synchronizer( lock );
}
@Test
public void executeWithRunnable() {
Runnable runnable = mock( Runnable.class );
synchronizer.execute( runnable );
verifyRunnableLockHandlingOnExecute( runnable );
}
@Test
public void executeWithExceptionThrowingRunnable() {
RuntimeException expected = new RuntimeException();
Runnable runnable = mock( Runnable.class );
doThrow( expected ).when( runnable ).run();
Throwable actual = thrownBy( () -> synchronizer.execute( runnable ) );
assertSame( expected, actual );
verifyRunnableLockHandlingOnExecute( runnable );
}
@Test
public void executeWithExceptionThrowingSupplier() {
RuntimeException expected = new RuntimeException();
Supplier<Object> supplier = stubSupplier( new Object() );
doThrow( expected ).when( supplier ).get();
Throwable actual = thrownBy( () -> synchronizer.execute( supplier ) );
assertSame( expected, actual );
verifyRunnableLockHandlingOnExecute( supplier );
}
@Test
public void executeWithSupplier() {
Object expected = new Object();
Supplier<Object> supplier = stubSupplier( expected );
Object actual = synchronizer.execute( supplier );
assertSame( expected, actual );
verifyRunnableLockHandlingOnExecute( supplier );
}
@SuppressWarnings("unchecked")
private static Supplier<Object> stubSupplier( Object expected ) {
Supplier<Object> result = mock( Supplier.class );
when( result.get() ).thenReturn( expected );
return result;
}
private void verifyRunnableLockHandlingOnExecute( Runnable runnable ) {
InOrder order = inOrder( lock, runnable );
order.verify( lock ).lock();
order.verify( runnable ).run();
order.verify( lock ).unlock();
order.verifyNoMoreInteractions();
}
private void verifyRunnableLockHandlingOnExecute( Supplier<?> supplier ) {
InOrder order = inOrder( lock, supplier );
order.verify( lock ).lock();
order.verify( supplier ).get();
order.verify( lock ).unlock();
order.verifyNoMoreInteractions();
}
}