本文介绍了使用Moq和EF 4.1模拟UnitOfWork的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在通过Contoso示例进行一些TDD练习,并且我的招生考试都通过了.

I am working my way through the Contoso sample for some TDD practice and my tests for retrieving students are passing.

我创建新学生的测试失败了(尽管实际的代码可行),因为我认为没有嘲笑DBContext.

My test for creating a new student fails (although the actual code works) as I believe the DBContext is not being mocked.

我应该重构什么才能使测试过去?

What should I refactor in order to get this test to past?

测试因此失败:

Contoso.Tests.Controllers.StudentControllerTest.Create_HttpPost_Should_Save_New_Student: 预期:9 但是是:8

Contoso.Tests.Controllers.StudentControllerTest.Create_HttpPost_Should_Save_New_Student: Expected: 9 But was: 8

这里有具体的UnitOf工作

Heres the concrete UnitOfWork

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);
    }
}

StudentController

The StudentController

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);
    }

...
}

这是我模拟IUnitOfWork的地方

Here's where I mock the IUnitOfWork

    public static IUnitOfWork MockUnitOfWork(List<Student> students)
    {
        var mockUnitOfWork = new Mock<IUnitOfWork>();

        mockUnitOfWork.Setup(x => x.StudentsRepository.Students()).Returns(students.AsQueryable());

        return mockUnitOfWork.Object;
    }

这是考试不及格

private IUnitOfWork unitOfWork = UnitTestHelpers.MockUnitOfWork(testData);
...



    [Test]
    public void Create_HttpPost_Should_Save_New_Student()
    {
        // Arrange
        var studentsCount = unitOfWork.StudentsRepository.Students().Count();
        var controller = new StudentController(unitOfWork);
        var student = Fakes.FakeStudentsData.CreateStudent();

        // Act
        var result = controller.Create(student);

        // Assert
        Assert.AreEqual(studentsCount+1, unitOfWork.StudentsRepository.Students().Count());
        Assert.IsInstanceOf(typeof(RedirectToRouteResult), result);
    }

推荐答案

似乎还需要模拟StudentRepository的Add方法.我不确定语法是否正确,但是请尝试以下操作:

It looks like the Add method for StudentRepository needs to be mocked as well. I'm not if sure if the syntax is right, but try the following:

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;
}

这篇关于使用Moq和EF 4.1模拟UnitOfWork的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-29 19:08