【问题标题】:Mock default role provider for controller's action unit test控制器动作单元测试的模拟默认角色提供者
【发布时间】:2013-03-11 03:15:32
【问题描述】:

希望这不是一个愚蠢的问题。两天来,我一直在寻找一种方法来模拟对我的操作调用 system.web.security.roles 的方法。

我希望我的单元测试是独立的,并且不涉及对外部资源的调用,例如存储角色的数据库。

我找到的所有答案都建议创建自定义角色提供程序,但我更喜欢嘲笑创建假货。

我得到的最接近的是solution,但我没有找到一种方法让 ninject 在测试之外运行项目时将默认角色 Provider 传递给构造函数。

我知道 Mock 类型为此提供了更简单的解决方案,但我正在使用 rhino Mocks,现在更改为时已晚。

【问题讨论】:

    标签: asp.net-mvc-3 unit-testing mocking ninject roleprovider


    【解决方案1】:

    我遇到了和你一样的问题,搜索了两个小时后我放弃了。

    最后我创建了自己的模拟角色提供者 - 代码如下。

    public class MockRoleProvider : RoleProvider
    {
        public MockRoleProvider()
            : base()
        {
            Users = new List<User>();
            Roles = new List<Role>();
        }
    
        #region RoleProvider members
        public override void AddUsersToRoles(string[] usernames, string[] roleNames)
        {
            if (usernames == null) throw new ArgumentNullException("usernames");
            if (roleNames == null) throw new ArgumentNullException("roleNames");
    
            foreach (string role in roleNames)
            {
                if (!RoleExists(role)) throw new ProviderException("Role name does not exist.");
            }
    
            foreach (string user in usernames)
            {
                if (Users.FirstOrDefault(u => u.Username == user) == null) throw new ProviderException("Username does not exist.");
            }
    
            foreach (string username in usernames)
            {
                User user = Users.FirstOrDefault(u => u.Username == username);
                if (user == null) continue;
                foreach (var rolename in roleNames)
                {
                    Role role = Roles.FirstOrDefault(r => r.RoleName == rolename);
                    user.Roles.Add(role);
                    role.Users.Add(user);
                }
            }
        }
    
        public override string ApplicationName { get; set; }
    
        public override void CreateRole(string roleName)
        {
            if (roleName == null || roleName == "") throw new ProviderException("Role name cannot be empty or null.");
            if (roleName.Contains(",")) throw new ArgumentException("Role names cannot contain commas.");
            if (RoleExists(roleName)) throw new ProviderException("Role name already exists.");
    
            Roles.Add(new Role { RoleName = roleName });
        }
    
        public override bool DeleteRole(string roleName, bool throwOnPopulatedRole)
        {
            if (roleName == null || roleName == "") throw new ProviderException("Role name cannot be empty or null.");
    
            Role role = Roles.FirstOrDefault(r => r.RoleName == roleName);
    
            if (role == null) throw new ProviderException("Role name does not exist.");
            if (throwOnPopulatedRole && GetUsersInRole(roleName).Length > 0) throw new ProviderException("Cannot delete a populated role.");
    
            Roles.Remove(Roles.FirstOrDefault(r => r.RoleName == roleName));
            return true;
        }
    
        public override string[] FindUsersInRole(string roleName, string usernameToMatch)
        {
            return GetUsersInRole(roleName).Where(n => n.Contains(usernameToMatch)).ToArray();
        }
    
        public override string[] GetAllRoles()
        {
            return Roles.Select(r => r.RoleName).ToArray();
        }
    
        public override string[] GetRolesForUser(string username)
        {
            if (username == null || username == "") throw new ProviderException("User name cannot be empty or null.");
    
            User user = Users.FirstOrDefault(u => u.Username == username);
    
            if (user == null) return new string[0];
    
            return user.Roles.Select(r => r.RoleName).ToArray();
        }
    
        public override string[] GetUsersInRole(string roleName)
        {
            if (roleName == null || roleName == "") throw new ProviderException("Role name cannot be empty or null.");
    
            Role role = Roles.FirstOrDefault(r => r.RoleName == roleName);
    
            if (role == null) throw new ProviderException("Role '" + roleName + "' does not exist.");
    
            return role.Users.Select(u => u.Username).OrderBy(n => n).ToArray();
        }
    
        public override bool IsUserInRole(string username, string roleName)
        {
            if (username == null || username == "") throw new ProviderException("User name cannot be empty or null.");
            if (roleName == null || roleName == "") throw new ProviderException("Role name cannot be empty or null.");
    
            Role role = Roles.FirstOrDefault(r => r.RoleName == roleName);
    
            return role != null && role.Users.FirstOrDefault(u => u.Username == username) != null;
        }
    
        public override void RemoveUsersFromRoles(string[] usernames, string[] roleNames)
        {
            foreach (string roleName in roleNames)
            {
                if (roleName == null || roleName == "") throw new ProviderException("Role name cannot be empty or null.");
                if (!RoleExists(roleName)) throw new ProviderException("Role name not found.");
            }
    
            foreach (string username in usernames)
            {
                if (username == null || username == "") throw new ProviderException("User name cannot be empty or null.");
    
                foreach (string roleName in roleNames)
                {
                    if (!IsUserInRole(username, roleName)) throw new ProviderException("User is not in role.");
                }
            }
    
            foreach (string username in usernames)
            {
                User user = Users.FirstOrDefault(u => u.Username == username);
                if (user == null) continue;
                foreach (string roleName in roleNames)
                {
                    Role role = user.Roles.FirstOrDefault(r => r.RoleName == roleName);
                    role.Users.Remove(user);
                    user.Roles.Remove(role);
                }
            }
        }
    
        public override bool RoleExists(string roleName)
        {
            if (roleName == null || roleName == "") throw new ProviderException("Role name cannot be empty or null.");
    
            return Roles.FirstOrDefault(r => r.RoleName == roleName) != null;
        }
        #endregion
    
        public void ClearAll()
        {
            Users = new List<User>();
            Roles = new List<Role>();
        }
    
        public void ClearRoles()
        {
            Roles = new List<Role>();
            Users.ForEach(u => u.Roles = new List<Role>());
        }
    
        public void ClearUsers()
        {
            Users = new List<User>();
            Roles.ForEach(r => r.Users = new List<User>());
        }
    
        public void CreateUser(string username)
        {
            if (username == null || username == "") throw new ProviderException("User name cannot be empty or null.");
            if (UserExists(username)) throw new ProviderException("User name already exists.");
    
            Users.Add(new User { Username = username });
        }
    
        public bool DeleteUser(string username)
        {
            if (username == null || username == "") throw new ProviderException("User name cannot be empty or null.");
    
            User user = Users.FirstOrDefault(u => u.Username == username);
    
            if (user == null) throw new ProviderException("User name does not exist.");
    
            foreach (Role role in user.Roles)
            {
                role.Users.Remove(user);
            }
            Users.Remove(user);
            return true;
        }
    
        public bool UserExists(string username)
        {
            if (username == null || username == "") throw new ProviderException("User name cannot be empty or null.");
    
            return Users.FirstOrDefault(u => u.Username == username) != null;
        }
    
        private List<Role> Roles { get; set; }
    
        private List<User> Users { get; set; }
    
        private class Role
        {
            public Role()
            {
                Users = new List<User>();
            }
    
            public string RoleName { get; set; }
            public List<User> Users { get; set; }
        }
    
        private class User
        {
            public User()
            {
                Roles = new List<Role>();
            }
    
            public string Username { get; set; }
            public List<Role> Roles { get; set; }
        }
    }
    

    这是 RoleProvider 的基本但完整的实现。

    为了使用 MockRoleProvider 将这行 XML 添加到您的 App.config 到 &lt;configuration&gt; 元素中:

    <system.web>
      <roleManager enabled="true" defaultProvider="MockRoleProvider">
        <providers>
          <add name="MockRoleProvider" type="YourProject.Tests.MockRoleProvider, YourProject.Tests"/>
        </providers>
      </roleManager>
    </system.web>
    

    然后在单元测试安排部分使用此代码:

    MockRoleProvider mock = Roles.Provider as MockRoleProvider;
    if (mock == null) throw new NullReferenceException("MockRoleProvider null exception.");
    mock.ClearAll();
    mock.CreateUser("SomeUser");
    mock.CreateRole("SomeRole");
    mock.AddUsersToRoles(new string[] { "SomeUser" }, new string[] { "SomeRole" });
    

    【讨论】:

    • 我刚刚设置了这个,效果很好,所以我投了赞成票。
    • N4n0 应该真的接受这个,这是一个很好的解决方案,赞成。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-12-10
    • 1970-01-01
    • 2012-02-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-07-30
    相关资源
    最近更新 更多