这是一种方法。
我遇到的另一种选择是:
创建您的 edmx 文件,删除自定义工具,使其不会自动生成实体。
打开edmx文件,右键添加代码生成项——进入数据库下的在线模板,选择EF POCO mockobject generator。这将创建两个 T4 模板(一个用于实体,另一个用于对象上下文和模拟对象上下文)。
一个 T4 模板将为您生成 poco 实体。另一个 T4 模板将创建一个您可以扩展的接口,以用作在实际对象上下文和模拟对象上下文中实现的工作单元。扩展它只需要修改 T4 模板以在生成的接口 (void SaveChanges()) 上包含一个附加方法,并在模拟对象上下文中实现该方法。
我发现它工作得很好。
尽管出于单元测试的目的,您不会想要测试您的工作单元(除非验证某些对象被添加/删除等)。您将改为测试具有预定义职责的存储库 - 通常在上下文中定义(例如患者预约)。
你会这样做:
public class PatientAppointmentRepository : IPatientAppointmentRepository
{
//Injected via IOC in constructor
private readonly IUnitOfWork _unitOfWork;
private readonly IPatientAppointmentLogic _patientAppointmentLogic;
public void CreateAppointment(PatientAppointmentModel model)
{
var appointment = ModelMapper.Instance.To<PatientAppointment>(model);
var appointmentAdded = _patientAppointmentLogic.Add(appointment);
if(appointmentAdded)
_unitOfWork.SaveChanges();
}
}
public class PatientAppointmentLogic : IPatientAppointmentLogic
{
private readonly IUnitOfWork _unitOfWork; //Set via constructor
private readonly PatientLogic _patientLogic;
public bool Validate(PatientAppointment appointment)
{
if(appointment == null)
throw new ArgumentNullException("appointment");
//perform some logic here
return true;
}
public void Add(PatientAppointment appointment)
{
if(appointment == null)
throw new ArgumentNullException("appointment");
if(!Validate(appointment)) return; //Or throw an exception, up to you
var patient = _patientLogic.GetById(appointment.PatientId);
if(patient == null) return;
patient.PatientAppointments.Add(appointment);
}
}
这完全取决于您是否适当地构建它。您可以拥有另一个具有基本验证的 AppointmentLogic 存储库作为示例。
理想情况下,通用验证不应依赖于外部资源(例如数据库)。
您应该能够一口气创建一个验证上下文,用于进一步验证(在验证“昂贵”之前首先是有效的“便宜”)。
有时,验证所需的所有“值”都在您需要的实体内,然后将其用作验证上下文。
祝你好运!