### Question:
Warn implements Punishment { @Override public PunishResult punish(PunishmentParameters punishmentParameters) { return punishmentService.punish(punishmentParameters, PunishmentType.WARN).ifPresent(punishmentRecord -> { PunishmentData punishmentData = dataProvider.getPunishmentsFor(punishmentRecord.getTarget().getUuid()); if (punishmentData.getWarns() == warnThreshold) { ban.punish(punishmentParameters); punishmentData.setWarns(0); } else { punishmentData.setWarns(punishmentData.getWarns() + 1); } punishmentDataRepository.update(punishmentData); }); }  @Override PunishResult punish(PunishmentParameters punishmentParameters);  }### Answer:
@Test public void punish() { PunishmentService service = mock(PunishmentService.class); PunishmentDataRepository dataRepository = mock(PunishmentDataRepository.class); Ban ban = mock(Ban.class); Warn warn = new Warn( service, dataProvider, dataRepository, ban, 3 ); PunishmentRecord record = mock(PunishmentRecord.class); when(record.getTarget()).thenAnswer(invocation -> { PlayerProfile profile = mock(PlayerProfile.class); when(profile.getUuid()).thenReturn(playerId); return profile; }); PunishmentParameters parameters = new PunishmentParameters( "target", "punisher", "reason", Duration.ofDays(10) ); when(service.punish(eq(parameters), eq(PunishmentType.WARN))).thenReturn( new PunishResult( record, PunishResultType.OK ) ); Runnable punish = () -> warn.punish(parameters); this.warn(1, punishmentData -> verify(punishmentData).setWarns(eq(2)), punish); this.warn(3, punishmentData -> { verify(ban).punish(same(parameters)); verify(punishmentData).setWarns(eq(0)); }, punish); }