Rhino Mock --- 我演我
  好了,看看第二个问题。一开始,我们依乎不觉得这是个大问题,不是直接创建一个依赖美吗,创建完了呗,一行代码而已。仍然,需要提醒注意,我们是在做商业软件。一旦展开了,一个类不可能只是一、两个类,特别是间接关联的,会更多,拔出萝卜带出泥。拿这个考试类来说,在我们的实际项目中,它还有考试科目列表属性,还通过报考类与考生有间接联系。而报考类又与订单类,事务类有交互有关系。考虑所有这些级联关系,难道我为了测试这个构造赋值功能把所有的类全部创建出来?
  再进一步思考,我们会给出一个自然的解决方案,把考区类,考试定义类抽象出两个接口来,构造器传入接口定义,而不是类本身。这其实是对层与层之间依赖注入的一个模仿。但是,相信我,这个方向是另一个梦魇的入口。业务域和多层之间完全是不同的环境。不想太深入讨论,可能独立一篇文章都打不住。
  幸好,我们有另一个工具Rhino Mock,能帮助我们解决类的模拟的问题。改造之后的测试代码如下。的影响是,你需要为被模拟的类,加入一个至少是protected的无参数构造器。这其实不是个大问题,如果你同时在项目中使用nHibernate的话,也会有类似的要求。
  看代码:
public class When_create_an_exam
{
private Establish context =
() =>
{
stub_exam_def = MockRepository.GenerateMock<ExamDef>();
stub_district = MockRepository.GenerateMock<District>();
stub_date = MockRepository.GenerateMock<Date>();
};
//...此处省略的没有修改的代码
}
  可以看到,这一次的重构,把考试代码、考区代码等,其实你根本不关心的信息已经省略掉了。
  AutoMocking --- 懒的高境界
  到这还不够,后一个问题是填饱我们肚子的有一块烧饼。
  隆重介绍AutoMocking,自动模拟。当你的测试类从AutoMock的Specification类继承时,它会自动为你创建一个被测试对象subject,并且根据被测试对象构建器的参数定义,全自动的创建模拟对象。而引用这些模拟对象的方式,
  很简单Dependency<ExamDef>,是依赖注入的依赖这个词。已经不需要太多的解释---名如其实。
  再看代码:
public class When_create_an_exam:Specification<Exam>
{
private It should_assign_to_properties =
() =>
{
subject.District.ShouldEqual(DependencyOf<District>());
subject.ExamDef.ShouldEqual(DependencyOf<ExamDef>());
subject.Date.ShouldEqual(DependencyOf<Date>());
};
}
  三行实现代码,对应三行测试代码。简洁的不能再简洁了。