### Question:
ProtocolListener implements JobExecutionListener, Ordered { @Override public void afterJob(JobExecution jobExecution) { StringBuilder protocol = new StringBuilder(); protocol.append("\n"); protocol.append(createFilledLine('*')); protocol.append(createFilledLine('-')); protocol.append("Protocol for " + jobExecution.getJobInstance().getJobName() + " \n"); protocol.append(" Started: " + jobExecution.getStartTime() + "\n"); protocol.append(" Finished: " + jobExecution.getEndTime() + "\n"); protocol.append(" Exit-Code: " + jobExecution.getExitStatus().getExitCode() + "\n"); protocol.append(" Exit-Descr: " + jobExecution.getExitStatus().getExitDescription() + "\n"); protocol.append(" Status: " + jobExecution.getStatus() + "\n"); protocol.append(" Content of Job-ExecutionContext:\n"); for (Entry<String, Object> entry : jobExecution.getExecutionContext().entrySet()) { protocol.append(" " + entry.getKey() + "=" + entry.getValue() + "\n"); } protocol.append(" Job-Parameter: \n"); JobParameters jp = jobExecution.getJobParameters(); for (Iterator<Entry<String, JobParameter>> iter = jp.getParameters().entrySet().iterator(); iter.hasNext();) { Entry<String, JobParameter> entry = iter.next(); protocol.append(" " + entry.getKey() + "=" + entry.getValue() + "\n"); } protocol.append(createFilledLine('-')); for (StepExecution stepExecution : jobExecution.getStepExecutions()) { protocol.append("Step " + stepExecution.getStepName() + " \n"); protocol.append(" ReadCount: " + stepExecution.getReadCount() + "\n"); protocol.append(" WriteCount: " + stepExecution.getWriteCount() + "\n"); protocol.append(" Commits: " + stepExecution.getCommitCount() + "\n"); protocol.append(" SkipCount: " + stepExecution.getSkipCount() + "\n"); protocol.append(" Rollbacks: " + stepExecution.getRollbackCount() + "\n"); protocol.append(" Filter: " + stepExecution.getFilterCount() + "\n"); protocol.append(" Content of Step-ExecutionContext:\n"); for (Entry<String, Object> entry : stepExecution.getExecutionContext().entrySet()) { protocol.append(" " + entry.getKey() + "=" + entry.getValue() + "\n"); } protocol.append(createFilledLine('-')); } protocol.append(createFilledLine('*')); LOGGER.info(protocol.toString()); }  @Override void afterJob(JobExecution jobExecution); @Override void beforeJob(JobExecution jobExecution); @Override int getOrder();  }### Answer:
@Test public void createProtocol() throws Exception { JobExecution jobExecution = new JobExecution(1L, new JobParametersBuilder().addString("test", "value").toJobParameters()); jobExecution.setJobInstance(new JobInstance(1L, "test-job")); jobExecution.setCreateTime(new Date()); jobExecution.setStartTime(new Date()); jobExecution.setEndTime(new Date()); jobExecution.setExitStatus(new ExitStatus("COMPLETED_WITH_ERRORS", "This is a default exit message")); jobExecution.getExecutionContext().put("jobCounter", 1); StepExecution stepExecution = jobExecution.createStepExecution("test-step-1"); stepExecution.getExecutionContext().put("stepCounter", 1); ProtocolListener protocolListener = new ProtocolListener(); protocolListener.afterJob(jobExecution); String output = this.outputCapture.toString(); assertThat(output, containsString("Protocol for test-job")); assertThat(output, containsString("COMPLETED_WITH_ERRORS")); }