单元测试与实体框架。嘲讽

时间:2012-07-19 13:31:12

标签: entity-framework unit-testing

我是单元测试的初学者。请帮帮我

我上课 UserData UserData.cs

public partial class UserData
{

    /// <summary>
    /// return all not locked users
    /// </summary>
    /// <returns></returns>
    public static List<UserData> GetAllNotLockedUsers()
    {
        using (var db = new VostokPortalEntities())
        {
            var result = db.UserData.Where(i => !i.IsLocked).ToList();
            return result;
        }
        throw new Exception("cannot get users");
    }
}

我有控制器动作

    [HttpGet]
    public ActionResult Index()
    {           
        //get all user list
        var users = UserData.GetAllNotLockedUsers();
        return View(users);
    }

我有测试方法

[TestMethod]
public void UserPageUnAuth()
{
    var fakedHttpContext = TestCore.FakeHttpContext();
    var homeController = new HomeController(fakedHttpContext);
    var indexResult = homeController.Index() as ViewResult;
    Assert.IsNotNull(indexResult);
}

我想用Mock测试一下。 我该怎么办? 我应该用存储库模式重写类吗?这是必要的吗? 我应该重写控制器逻辑吗? 我应该为EF自动生成的类添加一些代码 互联网上有关于初学者单元测试的文章吗? 有没有简单的方法来模拟EF?

1 个答案:

答案 0 :(得分:1)

将DB操作移动到Repository类是个好主意。您应该首先为存储库创建一个接口。

public interface IUserRepository
{
    IEnumerable<User> GetAllNotLockedUsers();
}

然后你应该实现一个非静态的存储库类。

public class UserRepository : IUserRepository
{
    public IEnumerable<User> GetAllNotLockedUsers()
    {
        using (var db = new VostokPortalEntities())
        {
            var result = db.UserData.Where(i => !i.IsLocked).ToList();
            return result;
        }
    }
}

由于存储库不再是静态的,因此在使用它之前必须在某处实例化它。但是,下面的代码将无法测试。

[HttpGet]
public ActionResult Index()
{           
    var repository = new UserRepository();
    return View(repository.GetAllNotLockedUsers());
}

在函数内部创建了存储库,因此您无法将其替换为模拟测试。您可以使用构造函数注入来注入此对象。

public class MyController : Controller
{
    private readonly IUserRepository _repository;

    public MyController(IUserRepository repository)
    {
        _repository = repository;
    }
}

现在MyController是可测试的,因为你可以注入一个模拟实例而不是具体的实现。

[Test]
public void RepositoryTest()
{
    //using Moq here
    Mock<IUserRepository> repositoryMock = new Mock<IUserRepository>();
    MyController controller = new MyController(repositoryMock.Object);
}

但是,如果没有无参数构造函数,默认控制器工厂将无法创建控制器。它对您的存储库实现一无所知。从现在开始,您应该获得DI容器的帮助来创建控制器。我不会详细介绍,您可以查看this blog post