我正在使用Moq和MvcContrib TestHelper类为ASP.NET MVC 1.0中的项目编写单元测试.我遇到了一个问题. 当我来到我的AccountController中的Roles.AddUserToRole时,我得到一个System.NotSupportedException. Roles类是静
当我来到我的AccountController中的Roles.AddUserToRole时,我得到一个System.NotSupportedException. Roles类是静态的,Moq不能模拟静态类.
我能做什么?
您可以使用像DI(依赖注入)这样的模式.在您的情况下,我会将RoleProvider传递给AccountController,默认情况下它将是默认的RoleProvider,并且是测试中的模拟对象.就像是:public class AccountController
{
private MembershipProvider _provider;
private RoleProvider roleProvider;
public AccountController()
: this(null, null)
{
}
public AccountController(MembershipProvider provider, RoleProvider roleProvider)
{
_provider = provider ?? Membership.Provider;
this.roleProvider = roleProvider ?? System.Web.Security.Roles.Provider;
}
}
MVC运行时将调用默认构造函数,而构造函数又将使用默认角色提供程序初始化AccountController.在单元测试中,您可以直接调用重载的构造函数,并传递MockRoleProvider(或使用Moq为您创建):
[Test]
public void AccountControllerTest()
{
AccountController controller = new AccountController(new MockMembershipProvider(), new MockRoleProvider());
}
编辑:这是我如何模拟整个HttpContext,包括主要用户.
要获取HttpContext的Moq版本:
public static HttpContextBase GetHttpContext(IPrincipal principal)
{
var httpContext = new Mock<HttpContextBase>();
var request = new Mock<HttpRequestBase>();
var response = new Mock<HttpResponseBase>();
var session = new Mock<HttpSessionStateBase>();
var server = new Mock<HttpServerUtilityBase>();
var user = principal;
httpContext.Setup(ctx => ctx.Request).Returns(request.Object);
httpContext.Setup(ctx => ctx.Response).Returns(response.Object);
httpContext.Setup(ctx => ctx.Session).Returns(session.Object);
httpContext.Setup(ctx => ctx.Server).Returns(server.Object);
httpContext.Setup(ctx => ctx.User).Returns(user);
return httpContext.Object;
}
Principal的模拟实现:
public class MockPrincipal : IPrincipal
{
private IIdentity _identity;
private readonly string[] _roles;
public MockPrincipal(IIdentity identity, string[] roles)
{
_identity = identity;
_roles = roles;
}
public IIdentity Identity
{
get { return _identity; }
set { this._identity = value; }
}
public bool IsInRole(string role)
{
if (_roles == null)
return false;
return _roles.Contains(role);
}
}
MockIdentity:
public class MockIdentity : IIdentity
{
private readonly string _name;
public MockIdentity(string userName) {
_name = userName;
}
public override string AuthenticationType
{
get { throw new System.NotImplementedException(); }
}
public override bool IsAuthenticated
{
get { return !String.IsNullOrEmpty(_name); }
}
public override string Name
{
get { return _name; }
}
}
神奇的召唤:
MockIdentity identity = new MockIdentity("JohnDoe");
var httpContext = MoqHelpers.GetHttpContext(new MockPrincipal(identity, null));
请注意,我编辑了上面的代码,省略了一些自定义的东西,但我很确定这应该仍然有效.
