Unit testing Moq和EF 4.1模拟工作单元
我正在通过Contoso样本进行一些TDD实践,我检索学生的测试正在通过 我创建一个新学生的测试失败了(尽管实际的代码是有效的),因为我相信DBContext没有被模仿 我应该重构什么才能让这个测试通过 测试失败,因此: Contoso.Tests.Controllers.StudentControllerTest.Create\u HttpPost\u应保存\u新建\u学生: 预期:9 但结果是:8 这是具体的工作单元Unit testing Moq和EF 4.1模拟工作单元,unit-testing,asp.net-mvc-3,moq,unit-of-work,Unit Testing,Asp.net Mvc 3,Moq,Unit Of Work,我正在通过Contoso样本进行一些TDD实践,我检索学生的测试正在通过 我创建一个新学生的测试失败了(尽管实际的代码是有效的),因为我相信DBContext没有被模仿 我应该重构什么才能让这个测试通过 测试失败,因此: Contoso.Tests.Controllers.StudentControllerTest.Create\u HttpPost\u应保存\u新建\u学生: 预期:9 但结果是:8 这是具体的工作单元 public class UnitOfWork : IUnitOfWork
public class UnitOfWork : IUnitOfWork
{
private SchoolContext context = new SchoolContext();
private IStudentsRepository studentsRepository;
private bool disposed = false;
public IStudentsRepository StudentsRepository
{
get
{
if (this.studentsRepository == null)
{
this.studentsRepository = new StudentsRepository(context);
}
return studentsRepository;
}
}
public void Save()
{
context.SaveChanges();
}
protected virtual void Dispose(bool disposing)
{
if (!this.disposed)
{
if (disposing)
{
context.Dispose();
}
}
this.disposed = true;
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
}
public static IUnitOfWork MockUnitOfWork(List<Student> students)
{
var mockUnitOfWork = new Mock<IUnitOfWork>();
mockUnitOfWork.Setup(x => x.StudentsRepository.Students()).Returns(students.AsQueryable());
return mockUnitOfWork.Object;
}
学生控制员
public class StudentController : Controller
{
private IUnitOfWork _unitOfWork;
public StudentController(IUnitOfWork unitOfWork)
{
this._unitOfWork = unitOfWork;
}
...
[HttpPost]
public ActionResult Create(Student student)
{
if (ModelState.IsValid)
{
_unitOfWork.StudentsRepository.Add(student);
_unitOfWork.StudentsRepository.Save();
return RedirectToAction("Details", new { id = student.StudentID });
}
return View(student);
}
...
}
这就是我嘲笑工作的地方
public class UnitOfWork : IUnitOfWork
{
private SchoolContext context = new SchoolContext();
private IStudentsRepository studentsRepository;
private bool disposed = false;
public IStudentsRepository StudentsRepository
{
get
{
if (this.studentsRepository == null)
{
this.studentsRepository = new StudentsRepository(context);
}
return studentsRepository;
}
}
public void Save()
{
context.SaveChanges();
}
protected virtual void Dispose(bool disposing)
{
if (!this.disposed)
{
if (disposing)
{
context.Dispose();
}
}
this.disposed = true;
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
}
public static IUnitOfWork MockUnitOfWork(List<Student> students)
{
var mockUnitOfWork = new Mock<IUnitOfWork>();
mockUnitOfWork.Setup(x => x.StudentsRepository.Students()).Returns(students.AsQueryable());
return mockUnitOfWork.Object;
}
看起来StudentRepository的Add方法也需要模拟。我不确定语法是否正确,但请尝试以下操作:
public static IUnitOfWork MockUnitOfWork(List<Student> students)
{
var mockUnitOfWork = new Mock<IUnitOfWork>();
mockUnitOfWork.Setup(x => x.StudentsRepository.Students()).Returns(students.AsQueryable());
mockUnitOfWork.Setup(x => x.StudentsRepository.Add(It.IsAny<Student>())).Callback<Student>((s) => students.Add(s));
return mockUnitOfWork.Object;
}
publicstaticiunitofwork MockUnitOfWork(列出学生)
{
var mockUnitOfWork=new Mock();
mockUnitOfWork.Setup(x=>x.StudentsRepository.Students()).Returns(Students.AsQueryable());
mockUnitOfWork.Setup(x=>x.StudentsRepository.Add(It.IsAny()).Callback((s)=>students.Add));
返回mockUnitOfWork.Object;
}
您能提供StudentController的来源吗?抛出了什么异常?@Restuta测试失败-没有异常。好的,两个断言中的哪一个失败了?Assert.AreEqual-预期为:9,但很抱歉重新提出这个问题,但是示例代码在哪里?我正在编写我自己的应用程序,它的控制器也实现UnitOfWork,我想知道我是否应该将UnitOfWork注入我的控制器,以及这一切是如何工作的(为了将来对我的控制器进行单元测试)。谢谢谢谢通过了测试。在添加新学生时,是否有增加ID的方法?您可能可以使用如下内容扩展回调:…回调((s)=>{students.Add(s);s.ID=students.Select(x=>x.ID).Max()+1;});酷。今晚我会试试看,我正在考虑在添加新学生后重定向到详细信息页面,所以我必须通过ID。网络上有学习模仿的好教程吗?Moq快速入门非常好(),还有其他链接。哦,当然!以前去过那里,但现在它更相关了。