asp.net-mvc - Moq Roles.AddUserToRole 测试

标签 asp.net-mvc unit-testing static moq

我正在使用 Moq 和 MvcContrib TestHelper 类为 ASP.NET MVC 1.0 中的项目编写单元测试。我遇到了一个问题。

当我来到 AccountController 中的 Roles.AddUserToRole 时,我得到一个 System.NotSupportedException。 Roles 类是静态的,Moq 不能模拟静态类。

我能做些什么?

最佳答案

您可以使用像 DI(依赖注入(inject))这样的模式。在您的情况下,我会将 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());
}

编辑 : 这就是我如何 mock 整个 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);
    }
  }

模拟身份:
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));

请注意,我编辑了上面的代码以省略一些自定义内容,但我很确定这应该仍然有效。

关于asp.net-mvc - Moq Roles.AddUserToRole 测试,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1781745/

相关文章:

jquery - 为什么 jquery 需要一个 ui 对话框的选择器

unit-testing - PowerBuilder单元测试框架

c# - 从 NUnit TestContext 检索测试持续时间

Python 单元测试和何时模拟

java - 如何有效的使用静态方法?

c# - 试图覆盖 ClaimsIdentityFactory 上的 CreateAsync 函数

javascript - 如何仅捕获用户更改了值的多行中的那些列?

javascript - 使用多个下拉列表在单个 View 中过滤具有两个模型的数据表

c++ - main函数中静态对象的理解

swift - 为什么会出现 "Static member ' .. .' cannot be used on instance of type ' .. .'"错误?