【发布时间】:2012-02-20 21:15:27
【问题描述】:
我正在尝试为我的 MVC3 项目(该项目的第一个测试)编写一些单元测试,但我被难住了。基本上,我有一个 MemberQueries 类,我的 MemberController 使用它来处理所有逻辑。
我想开始编写这个类的测试,并想从一个简单的例子开始。我在这个类中有一个名为 IsEditModeAvailable 的方法,它确定用户是否是“站点管理员”角色的成员,或者用户是否能够编辑自己的数据,但不能编辑其他人。我通过将传入的 Id 值与 HttpContext User 属性进行比较来确定最后一个要求。
我遇到的问题是,在创建 MemberQueries 对象时,我不知道如何模拟或将正确的参数注入到我的单元测试中。我正在使用 NUnit、Moq 和 Ninject,但我只是不确定如何编写代码。如果我的结构不正确,请告诉我,因为我完全是单元测试的菜鸟。
这是我的 MemberQueries 类的代码示例:
public class MemberQueries : IMemberQueries
{
private readonly IRepository<Member> _memberRepository;
private readonly IMemberServices _memberServices;
private readonly IPrincipal _currentUser;
public MemberQueries(IUnitOfWork unitOfWork, IMemberServices memberServices, IPrincipal currentUser)
{
_memberRepository = unitOfWork.RepositoryFor<Member>();
_memberServices = memberServices;
_currentUser = currentUser;
}
public bool IsEditModeAvailable(int memberIdToEdit)
{
if (_currentUser.IsInRole("Site Administrator")) return true;
if (MemberIsLoggedInUser(memberIdToEdit)) return true;
return false;
}
public bool MemberIsLoggedInUser(int memberIdToEdit)
{
var loggedInUser = _memberServices.FindByEmail(_currentUser.Identity.Name);
if (loggedInUser != null && loggedInUser.Id == memberIdToEdit) return true;
return false;
}
}
这是我的 MemberServices 类的示例(在我的域项目中,由 MemberQueries 引用):
public class MemberServices : IMemberServices
{
private readonly IRepository<Member> _memberRepository;
public MemberServices(IUnitOfWork unitOfWork)
{
_memberRepository = unitOfWork.RepositoryFor<Member>();
}
public Member Find(int id)
{
return _memberRepository.FindById(id);
}
public Member FindByEmail(string email)
{
return _memberRepository.Find(m => m.Email == email).SingleOrDefault();
}
}
最后,这是我正在尝试编写的单元测试的存根:
[Test]
public void LoggedInUserCanEditTheirOwnInformation()
{
var unitOfWork = new UnitOfWork();
var currentUser = new Mock<IPrincipal>();
// I need to somehow tell Moq that the logged in user has a HttpContext.User.Name of "jdoe@acme.com"
var memberServices = new Mock<MemberServices>();
// I then need to tell Moq that it's FindByEmail("jdoe@acme.com") method should return a member with a UserId of 1
var memberQueries = new MemberQueries(unitOfWork, memberServices.Object, currentUser.Object);
// If the logged in user is "jdoe@acme.com" who has an Id of 1, then IsEditModeAvailable(1) should return true
Assert.IsTrue(memberQueries.IsEditModeAvailable(1));
}
【问题讨论】:
-
我在你的代码中没有看到对
HttpContext.Current的引用。 -
达林,我通过ninject注入HttpContext如下:`kernel.Bind
().ToMethod(ctx => HttpContext.Current.User).InRequestScope();` -
您尝试测试的代码不依赖于它。所以你可以完美地模拟一切。
标签: asp.net-mvc-3 unit-testing httpcontext