我如何模拟我的会员提供商(我有自定义会员资格提供商,但不知道如何模拟它并将会员资格作为提供者提供为Membership.Provider只有getter)并使用该模拟的自定义成员资格提供者我的单元测试?
这是我的控制器
public class MyController
{
private IMyRepository myRepository;
public MyController(IMyRepository myRepository)
{
this.myRepository= myRepository;
}
[HttpGet]
public ActionResult Create()
{
var user = Membership.GetUser(); // <--- I want mock this method
ViewBag.User = user;
return View("Create");
}
}
这是我的测试(使用Moq)
[TestClass]
public class MyControllerUnitTest
{
private MyController controller;
public MyControllerUnitTest()
{
Mock<IMyRepository > myRepository = new Mock<IMyRepository>();
var controller = new GroupController(myRepository.Object);
}
[TestMethod]
public void TestMethod1()
{
var result = controller.Create() as ViewResult;
Assert.AreEqual("Create", result.ViewName);
}
}
答案 0 :(得分:5)
@Sergey是对的,你不应该直接使用Membership
类。我知道在某些情况下您需要使用会员级别,因此添加以下信息。
您需要在类(从接口派生)中包装Membership
类,然后您可以在需要的地方进行模拟。
缩短我们所获得的版本:
public interface IMembershipService
{
MembershipUser GetUserDetails(string emailAddress);
void CreateUserRole(string roleName);
void AssignUserToRole(string username, string roleName);
bool ValidateUserCredentials(string username, string password);
void SetAuthenticationCookie(string username, bool rememberMe);
void SignOut();
void UpdateUser(MembershipUser membershipUser);
bool DeleteUser(string username);
}
public class MembershipService : IMembershipService
{
public MembershipUser GetUserDetails(string emailAddress)
{
return Membership.GetUser(emailAddress);
}
public MembershipUser GetUserDetails(Guid membershipId)
{
return Membership.GetUser(membershipId);
}
}
在你的控制器中,只需注入它:
public class AdminController : Controller
{
private readonly IMembershipService _membershipService;
private readonly IEmailService _emailService;
public AdminController(IMembershipService membershipService,
IEmailService emailService)
{
_membershipService = membershipService;
_emailService = emailService;
}
}
在单元测试中,你可以这样做:
var membershipService = new Mock<IMembershipService>();
答案 1 :(得分:2)
首先,您应该从MyController
类继承System.Web.Mvc.Controller
:
public class MyController : System.Web.Mvc.Controller
然后你应该避免使用Membership
。它是静态的,并非设计为可单元测试。更好的选择是使用控制器的User
属性:
[HttpGet]
public ActionResult Index()
{
ViewBag.UserName = this.User.Identity.Name;
return View("Index");
}
可以使用controller.User
:
ControllerContext
属性
// arrange
Mock<HttpContextBase> httpContext = new Mock<HttpContextBase>();
httpContext.SetupGet(c => c.User.Identity.Name).Returns("John Doe");
Mock<ControllerBase> baseControler = new Mock<ControllerBase>();
this.controller.ControllerContext =
new ControllerContext(httpContext.Object, new RouteData(), baseControler.Object);
// act
var result = this.controller.Index();
// assert
Assert.AreEqual("John Doe", ((ViewResult)result).ViewBag.UserName);