### Question:
DeferringLockClient implements Locks.Client { @Override public void releaseShared( ResourceType resourceType, long... resourceIds ) { assertNotStopped(); for ( long resourceId : resourceIds ) { removeLock( resourceType, resourceId, false ); } } DeferringLockClient( Locks.Client clientDelegate ); @Override void acquireShared( LockTracer tracer, ResourceType resourceType, long... resourceIds ); @Override void acquireExclusive( LockTracer tracer, ResourceType resourceType, long... resourceIds ); @Override boolean tryExclusiveLock( ResourceType resourceType, long resourceId ); @Override boolean trySharedLock( ResourceType resourceType, long resourceId ); @Override boolean reEnterShared( ResourceType resourceType, long resourceId ); @Override boolean reEnterExclusive( ResourceType resourceType, long resourceId ); @Override void releaseShared( ResourceType resourceType, long... resourceIds ); @Override void releaseExclusive( ResourceType resourceType, long... resourceIds ); @Override void prepare(); @Override void stop(); @Override void close(); @Override int getLockSessionId(); @Override Stream<? extends ActiveLock> activeLocks(); @Override long activeLockCount();  }### Answer:
@Test public void releaseOfNotHeldSharedLockThrows() { TestLocks actualLocks = new TestLocks(); TestLocksClient actualClient = actualLocks.newClient(); DeferringLockClient client = new DeferringLockClient( actualClient ); try { client.releaseShared( ResourceTypes.NODE, 42 ); fail( "Exception expected" ); } catch ( Exception e ) { assertThat( e, instanceOf( IllegalStateException.class ) ); } }
@Test public void shouldThrowWhenReleaseNotYetAcquiredShared() { Locks.Client actualClient = mock( Locks.Client.class ); DeferringLockClient client = new DeferringLockClient( actualClient ); try { client.releaseShared( ResourceTypes.NODE, 1 ); fail( "Expected exception" ); } catch ( IllegalStateException e ) { } }