我是单元测试的初学者。请帮帮我
我上课 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?
答案 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