模拟域对象" class="reference-link">10.6 模拟域对象

遇到了另一个常见的问题,同时为Spring Batch编写单元测试和集成测试组件是如何模拟域对象。一个很好的例子是StepExecutionListener,如下所示:

  1. public class NoWorkFoundStepExecutionListener extends StepExecutionListenerSupport {
  2. public ExitStatus afterStep(StepExecution stepExecution) {
  3. if (stepExecution.getReadCount() == 0) {
  4. throw new NoWorkFoundException("Step has not processed any items");
  5. }
  6. return stepExecution.getExitStatus();
  7. }
  8. }

上面的监听是框架提供的,并且它检测到stepExecution的read count是为空的,因此它表示没有工作要做。虽然这个例子相当简单,当试图单元测试类的时候它解释了可能遇到的问题类型,实现接口验证Spring Batch 域对象。考虑到上面的侦听器的单元测试:

  1. private NoWorkFoundStepExecutionListener tested = new NoWorkFoundStepExecutionListener();
  2. @Test
  3. public void testAfterStep() {
  4. StepExecution stepExecution = new StepExecution("NoProcessingStep",
  5. new JobExecution(new JobInstance(1L, new JobParameters(),
  6. "NoProcessingJob")));
  7. stepExecution.setReadCount(0);
  8. try {
  9. tested.afterStep(stepExecution);
  10. fail();
  11. } catch (NoWorkFoundException e) {
  12. assertEquals("Step has not processed any items", e.getMessage());
  13. }
  14. }

因为Spring Batch域模型遵循良好的面向对象原则,StepExecution需要一个JobExecution,JobExecution需要一个JobInstance和JobParameters为了创建一个有效的StepExecution。虽然这是很好的可靠的域模型,为了冗长的单元测试创建存根对象。为了解决这个问题,Spring Batch测试模块引入一个工厂来创建域对象:MetaDataInstanceFactory,把这个给到工厂,更新后的单元测试可以更简洁:

  1. private NoWorkFoundStepExecutionListener tested = new NoWorkFoundStepExecutionListener();
  2. @Test
  3. public void testAfterStep() {
  4. StepExecution stepExecution = MetaDataInstanceFactory.createStepExecution();
  5. stepExecution.setReadCount(0);
  6. try {
  7. tested.afterStep(stepExecution);
  8. fail();
  9. } catch (NoWorkFoundException e) {
  10. assertEquals("Step has not processed any items", e.getMessage());
  11. }
  12. }

上面的方法为了创建一个简单的StepExecution,它仅仅是便利的方法中可用的工厂。完整的方法清单可以在Javadoc找到