Moved testing of checkBeatForPublish from component test into unit test, and added test cases.
diff --git a/component-test/src/main/java/io/mifos/rhythm/AbstractRhythmTest.java b/component-test/src/main/java/io/mifos/rhythm/AbstractRhythmTest.java
index f01ec42..17862e5 100644
--- a/component-test/src/main/java/io/mifos/rhythm/AbstractRhythmTest.java
+++ b/component-test/src/main/java/io/mifos/rhythm/AbstractRhythmTest.java
@@ -146,10 +146,7 @@
 
     Assert.assertTrue(this.eventRecorder.wait(EventConstants.POST_BEAT, new BeatEvent(applicationName, beat.getIdentifier())));
 
-    Mockito.verify(beatPublisherServiceSpy, Mockito.timeout(2_000).atLeastOnce())
-            .checkBeatForPublish(anyObject(), eq(beatIdentifier), anyString(), eq(applicationName), eq(beat.getAlignmentHour()), anyObject());
-
-    Mockito.verify(beatPublisherServiceSpy, Mockito.times(1)).publishBeat(beatIdentifier, tenantDataStoreContext.getTenantName(), applicationName, expectedBeatTimestamp);
+    Mockito.verify(beatPublisherServiceSpy, Mockito.timeout(2_000).times(1)).publishBeat(beatIdentifier, tenantDataStoreContext.getTenantName(), applicationName, expectedBeatTimestamp);
 
     return beat;
   }
diff --git a/component-test/src/main/java/io/mifos/rhythm/TestBeats.java b/component-test/src/main/java/io/mifos/rhythm/TestBeats.java
index 5649fda..352005b 100644
--- a/component-test/src/main/java/io/mifos/rhythm/TestBeats.java
+++ b/component-test/src/main/java/io/mifos/rhythm/TestBeats.java
@@ -96,9 +96,6 @@
 
     Assert.assertTrue(this.eventRecorder.wait(EventConstants.POST_BEAT, new BeatEvent(appName, beat.getIdentifier())));
 
-    Mockito.verify(super.beatPublisherServiceSpy, Mockito.timeout(10_000).atLeast(3))
-            .checkBeatForPublish(anyObject(), eq(beatId), anyString(), eq(appName), eq(beat.getAlignmentHour()), anyObject());
-
-    Mockito.verify(beatPublisherServiceSpy, Mockito.times(3)).publishBeat(beatId, tenantDataStoreContext.getTenantName(), appName, expectedBeatTimestamp);
+    Mockito.verify(beatPublisherServiceSpy, Mockito.timeout(10_000).times(3)).publishBeat(beatId, tenantDataStoreContext.getTenantName(), appName, expectedBeatTimestamp);
   }
 }
\ No newline at end of file
diff --git a/service/src/main/java/io/mifos/rhythm/service/internal/service/BeatPublisherService.java b/service/src/main/java/io/mifos/rhythm/service/internal/service/BeatPublisherService.java
index 44a9989..1370305 100644
--- a/service/src/main/java/io/mifos/rhythm/service/internal/service/BeatPublisherService.java
+++ b/service/src/main/java/io/mifos/rhythm/service/internal/service/BeatPublisherService.java
@@ -33,6 +33,7 @@
 import java.time.temporal.ChronoUnit;
 import java.util.List;
 import java.util.Optional;
+import java.util.function.Predicate;
 import java.util.stream.Stream;
 
 import static io.mifos.rhythm.service.ServiceConstants.LOGGER_NAME;
@@ -87,23 +88,32 @@
           final String applicationName,
           final Integer alignmentHour,
           final LocalDateTime nextBeat) {
-    final long numberOfBeatPublishesNeeded = getNumberOfBeatPublishesNeeded(nextBeat, now);
+    return checkBeatForPublishHelper(now, alignmentHour, nextBeat, x -> publishBeat(beatIdentifier, tenantIdentifier, applicationName, x));
+  }
+
+  //Helper is separated from original function so that it can be unit-tested separately from publishBeat.
+  static Optional<LocalDateTime> checkBeatForPublishHelper(
+          final LocalDateTime now,
+          final Integer alignmentHour,
+          final LocalDateTime nextBeat,
+          final Predicate<LocalDateTime> publishSucceeded) {
+    final long numberOfBeatPublishesNeeded = getNumberOfBeatPublishesNeeded(now, nextBeat);
     if (numberOfBeatPublishesNeeded == 0)
       return Optional.empty();
 
     final Optional<LocalDateTime> firstFailedBeat = Stream.iterate(nextBeat,
             x -> incrementToAlignment(x, alignmentHour))
             .limit(numberOfBeatPublishesNeeded)
-            .filter(x ->!publishBeat(beatIdentifier, tenantIdentifier, applicationName, x))
+            .filter(x -> !publishSucceeded.test(x))
             .findFirst();
 
     if (firstFailedBeat.isPresent())
       return firstFailedBeat;
     else
-      return Optional.of(incrementToAlignment(nextBeat, alignmentHour));
+      return Optional.of(incrementToAlignment(now, alignmentHour));
   }
 
-  static long getNumberOfBeatPublishesNeeded(final @Nonnull LocalDateTime nextBeat, final LocalDateTime now) {
+  static long getNumberOfBeatPublishesNeeded(final LocalDateTime now, final @Nonnull LocalDateTime nextBeat) {
     if (nextBeat.isAfter(now))
       return 0;
 
@@ -114,4 +124,5 @@
   {
     return toIncrement.plusDays(1).truncatedTo(ChronoUnit.DAYS).plusHours(alignmentHour);
   }
+
 }
\ No newline at end of file
diff --git a/service/src/test/java/io/mifos/rhythm/service/internal/service/BeatPublisherServiceTest.java b/service/src/test/java/io/mifos/rhythm/service/internal/service/BeatPublisherServiceTest.java
index 1b36a9e..3d82b75 100644
--- a/service/src/test/java/io/mifos/rhythm/service/internal/service/BeatPublisherServiceTest.java
+++ b/service/src/test/java/io/mifos/rhythm/service/internal/service/BeatPublisherServiceTest.java
@@ -17,11 +17,13 @@
 
 import org.junit.Assert;
 import org.junit.Test;
+import org.mockito.Mockito;
 
 import java.time.LocalDateTime;
 import java.time.ZoneId;
 import java.time.temporal.ChronoUnit;
-import java.util.stream.Stream;
+import java.util.Optional;
+import java.util.function.Predicate;
 
 /**
  * @author Myrle Krantz
@@ -40,13 +42,50 @@
   @Test
   public void getNumberOfBeatPublishesNeeded() {
     final LocalDateTime now = LocalDateTime.now(ZoneId.of("UTC"));
-    final long eventsNeeded3 = BeatPublisherService.getNumberOfBeatPublishesNeeded(now.minus(3, ChronoUnit.DAYS), now);
+    final long eventsNeeded3 = BeatPublisherService.getNumberOfBeatPublishesNeeded(now, now.minus(3, ChronoUnit.DAYS));
     Assert.assertEquals(3, eventsNeeded3);
 
-    final long eventsNeededPast = BeatPublisherService.getNumberOfBeatPublishesNeeded(now.plus(1, ChronoUnit.DAYS), now);
+    final long eventsNeededPast = BeatPublisherService.getNumberOfBeatPublishesNeeded(now, now.plus(1, ChronoUnit.DAYS));
     Assert.assertEquals(0, eventsNeededPast);
 
-    final long eventsNeededNow = BeatPublisherService.getNumberOfBeatPublishesNeeded(now.minus(2, ChronoUnit.MINUTES), now);
+    final long eventsNeededNow = BeatPublisherService.getNumberOfBeatPublishesNeeded(now, now.minus(2, ChronoUnit.MINUTES));
     Assert.assertEquals(1, eventsNeededNow);
   }
+
+  @Test
+  public void checkBeatForPublishAllBeatsSucceed() {
+    final LocalDateTime now = LocalDateTime.now(ZoneId.of("UTC"));
+    final Optional<LocalDateTime> ret = BeatPublisherService.checkBeatForPublishHelper(now, 0, now.minus(3, ChronoUnit.DAYS), x -> true);
+    Assert.assertEquals(Optional.of(BeatPublisherService.incrementToAlignment(now, 0)), ret);
+  }
+
+  @Test
+  public void checkBeatForPublishFirstFails() {
+    final LocalDateTime now = LocalDateTime.now(ZoneId.of("UTC"));
+    final LocalDateTime nextBeat = now.minus(3, ChronoUnit.DAYS);
+    @SuppressWarnings("unchecked") final Predicate<LocalDateTime> produceBeatsMock = Mockito.mock(Predicate.class);
+    Mockito.when(produceBeatsMock.test(nextBeat)).thenReturn(false);
+    final Optional<LocalDateTime> ret = BeatPublisherService.checkBeatForPublishHelper(now, 0, nextBeat, produceBeatsMock);
+    Assert.assertEquals(Optional.of(nextBeat), ret);
+  }
+
+  @Test
+  public void checkBeatForPublishSecondFails() {
+    final LocalDateTime now = LocalDateTime.now(ZoneId.of("UTC"));
+    final LocalDateTime nextBeat = now.minus(3, ChronoUnit.DAYS);
+    final LocalDateTime secondBeat = BeatPublisherService.incrementToAlignment(nextBeat, 0);
+    @SuppressWarnings("unchecked") final Predicate<LocalDateTime> produceBeatsMock = Mockito.mock(Predicate.class);
+    Mockito.when(produceBeatsMock.test(nextBeat)).thenReturn(true);
+    Mockito.when(produceBeatsMock.test(secondBeat)).thenReturn(false);
+    final Optional<LocalDateTime> ret = BeatPublisherService.checkBeatForPublishHelper(now, 0, nextBeat, produceBeatsMock);
+    Assert.assertEquals(Optional.of(secondBeat), ret);
+  }
+
+  @Test
+  public void checkBeatForPublishNoneNeeded() {
+    final LocalDateTime now = LocalDateTime.now(ZoneId.of("UTC"));
+    final Optional<LocalDateTime> ret = BeatPublisherService.checkBeatForPublishHelper(now, 0, now.plus(1, ChronoUnit.DAYS),
+            x -> { Assert.fail("Pubish shouldn't be called"); return true; });
+    Assert.assertEquals(Optional.empty(), ret);
+  }
 }
\ No newline at end of file