### Question:
NexusActor extends TransportingActor<Nexus> implements TileableListener { @Override public void ballAccepted(Tileable tileable, Direction direction, Marble marble) { MarbleActor actor = MarbleActor.get(marble, getContext()); addActor(actor); Nexus nexus = getTileable(); Vector2 origin = getOrigin(direction); Vector2 center = getCenter(); Vector2 target = getTarget(direction); actor.setPosition(origin.x, origin.y, Align.center); actor.setDirection(direction.inverse()); Action moveCenter = Actions.moveToAligned(center.x, center.y, Align.center, origin.dst(center) * TRAVEL_TIME); Action moveTarget = Actions.moveToAligned(target.x, target.y, Align.center, target.dst(center) * TRAVEL_TIME); SequenceAction animation = new SequenceAction(); animation.addAction(moveCenter); animation.addAction(Actions.run(() -> { Direction out = Direction.BOTTOM; if (nexus.isReleasable(out, marble)) { actor.removeAction(animation); actor.setDirection(out); nexus.release(out, marble); nexus.getContext().setOccupied(false); } })); animation.addAction(moveTarget); animation.addAction(Actions.run(() -> { Direction inverse = direction.inverse(); if (!nexus.isReleasable(inverse, marble)) { ballAccepted(tileable, inverse, marble); return; } nexus.release(inverse, marble); })); actor.addAction(animation); } NexusActor(Nexus nexus, ActorContext context); @Override TextureRegion getTileTexture(); @Override void ballAccepted(Tileable tileable, Direction direction, Marble marble); @Override void act(float deltaTime);  }### Answer:
@Test public void testSpawn() throws Exception { assertThat(latch.await(5, TimeUnit.SECONDS)).isTrue(); latch = new CountDownLatch(2); TileableListener listener = spy(new TileableListener() { @Override public void ballAccepted(Tileable tileable, Direction direction, Marble marble) { latch.countDown(); } }); nexus.addListener(listener); assertThat(latch.await(5, TimeUnit.SECONDS)).isTrue(); verify(listener, atLeast(2)).ballAccepted(any(), any(), any()); }
@Test public void testInvalidDirection() throws Exception { assertThat(latch.await(5, TimeUnit.SECONDS)).isTrue(); assertThatThrownBy(() -> actor.ballAccepted(nexus, Direction.TOP, new Marble(MarbleType.BLUE)) ).isInstanceOf(IllegalArgumentException.class); }