单元测试工作单元

单元测试的新手。我有一个要进行单元测试的工作单元。我可能在这里缺少一些简单的东西。我正在尝试对Commit方法进行单元测试。我正在使用nunit和moq。
public class  UnitOfWork : IUnitOfWork
{
    private readonly DbContext _context;
    public UnitOfWork(DbContext ctx)
    {
        _context = ctx;
    }

    public void Commit()
    {
        _context.SaveChanges();
    }
}
我需要做什么来测试呢?     
已邀请:
        您将插入DBContext的模拟,然后验证在提交时调用了SaveChanges方法。
[Test]
public void Will_call_save_changes() {

  var mockContext = new Mock<DBContext>();
  var unitOfWork = new UnitOfWork(mockContext.Object);

  unitOfWork.Commit();


  mockContext.Verify(x => x.SaveChanges());

}
    
        您将需要模拟DbContext,然后验证是否调用了SaveChanges。 Moq之类的东西可以在这里为您提供帮助。     
        那是做到这一点的一种方式。 我遇到的另一个选择是: 创建您的edmx文件,删除自定义工具,使其不会自动生成实体。 打开edmx文件,右键单击并添加代码生成项-转到数据库下的在线模板,然后选择EF POCO模拟对象生成器。这将创建两个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存储库作为示例。 理想情况下,通用验证不应依赖于外部资源(例如数据库)。 您应该能够一口气创建一个验证上下文,该验证上下文将用于进一步的验证(先验证有效的“便宜”再验证“昂贵的”)。 有时,验证所需的所有“值”都在您仍然需要的实体内部,然后将其用作验证上下文。 祝你好运!     

要回复问题请先登录注册