现如今,单元测试已经变得相当普遍,那些还没有实践单元测试的开发者理应感到无地自容。在维基百科上对于单元测试是这样定义的:
  一种软件测试方法,利用这种方法对个别的源代码单元……进行测试,以确定这些单元是否适用。
  而在面向对象语言,尤其是Java语言中,通常的理解是“源代码的单元”即为某个方法。为了充分展现这一点,让我们引用一个来自于Spring的经典应用Pet Clinic中的一个示例,这里摘录了PetController类的部分代码,只是为了说明的方便起见:
  @Controller
  @SessionAttributes("pet")
  public class PetController {
  private final ClinicService clinicService;
  @Autowired
  public PetController(ClinicService clinicService) {
  this.clinicService = clinicService;
  }
  @ModelAttribute("types")
  public Collection<PetType> populatePetTypes() {
  return this.clinicService.findPetTypes();
  }
  @RequestMapping(value = "/owners/{ownerId}/pets/new", method = RequestMethod.GET)
  public String initCreationForm(@PathVariable("ownerId") int ownerId,
  Map<String, Object> model) {
  Owner owner = this.clinicService.findOwnerById(ownerId);
  Pet pet = new Pet();
  owner.addPet(pet);
  model.put("pet", pet);
  return "pets/createOrUpdatePetForm";
  }
  ...
  }正所我们所见,initCreationForm()方法的作用是加载用于创建新的Pet实例的表单。我们的目标是测试该方法的行为:
  在model中放入一个Pet的实例
  设置该Pet实例的Owner属性
  返回一个预定义的视图
  简单的传统单元测试

  正如上面所定义的一样,单元测试中需要用桩来取代方法中的依赖。下面是一个基于流行的Mockito框架所创建的典型单元测试:
  public class PetControllerTest {
  private ClinicService clinicService;
  private PetController controller;
  @Before
  public void setUp() {
  clinicService = Mockito.mock(ClinicService.class);
  controller = new PetController(clinicService);
  }
  @Test
  public void should_set_pet_in_model() {
  Owner dummyOwner = new Owner();
  Mockito.when(clinicService.findOwnerById(1)).thenReturn(dummyOwner);
  HashMap<String, Object> model = new HashMap<String, Object>();
  controller.initCreationForm(1, model);
  Iterator<Object> modelIterator = model.values().iterator();
  Assert.assertTrue(modelIterator.hasNext());
  Object value = modelIterator.next();
  Assert.assertTrue(value instanceof Pet);
  Pet pet = (Pet) value;
  Owner petOwner = pet.getOwner();
  Assert.assertNotNull(petOwner);
  Assert.assertSame(dummyOwner, petOwner);
  }
  }setUp()方法负责将controller进行初始化以便进行测试,同时也负责解析ClinicService这个依赖。Mockito将使用mock方式提供这个依赖的实现。
  should_set_pet_in_model()这个测试的目的是检查在主体方法运行后,该model应当包含一个Pet实例,并且该实例的Owner应当与经mock的ClinicService所返回的Owner相同。