加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > asp.Net > 正文

单元测试Raven和ASP.NET成员资格

发布时间:2020-12-16 06:46:02 所属栏目:asp.Net 来源:网络整理
导读:我正在启动一个Web应用程序,它将使用asp.net成员资格服务(带有sql server后端)来管理用户和RavenDb用于其他所有事情. 我是单位测试的新手,如果我可以通过一个示例方法跑过你迄今为止所拥有的东西,我会很感激. 这是HelixManager public class HelixManager:ID
我正在启动一个Web应用程序,它将使用asp.net成员资格服务(带有sql server后端)来管理用户和RavenDb用于其他所有事情.

我是单位测试的新手,如果我可以通过一个示例方法跑过你迄今为止所拥有的东西,我会很感激.

这是HelixManager

public class HelixManager:IDisposable
{
    private readonly IMembershipProvider _membership;
    private readonly IRepository _repos;

    public HelixManager()
    {
        _membership = new AspNetMembershipProvider(); 
        _repos = new RavenRepository();
    }

    public HelixManager(IMembershipProvider membershipProvider,IRepository repos) 
    { 
        _membership = membershipProvider;
        _repos = repos;
    }

    public User CreateAdmin(User newUser,string password)
    {
        if (String.IsNullOrEmpty(newUser.Email)) throw new ArgumentException("Email must be supplied");
        if (String.IsNullOrEmpty(password)) throw new ArgumentException("Password must be supplied");

        var memberId = _membership.CreateUser(newUser,password);

        if (memberId != null)
        {
            _membership.AddToRole(newUser,"Admin");

            newUser.Type = UserType.Admin;
            newUser.MemberId = memberId;

            _repos.Store<User>(newUser);
        }

        return newUser;
    }

这是IMembershipProvider

public interface IMembershipProvider
{
    string CreateUser(User newUser,string password);
    void AddToRole(User user,string rolename);
}

和实现AspNetMembershipProvider

public class AspNetMembershipProvider : IMembershipProvider
{
    public string CreateUser(User newUser,string password)
    {
        MembershipCreateStatus status;
        MembershipUser memUser = System.Web.Security.Membership.CreateUser(newUser.Email,password,newUser.Email,"",true,out status);
        return memUser.ProviderUserKey.ToString();
    }

    public void AddToRole(User user,string role)
    {
        Roles.AddUserToRole(user.Email,role);
    }
}

这是IRepository

public interface IRepository
{
    T Store<T>(T item);
}

它的实施

public class RavenRepository : IRepository
{
    private readonly DocumentStore _store;

    public RavenRepository()
    {
        _store = new DocumentStore { DefaultDatabase = "Helix",Url = "http://localhost:8080" };
        _store.Initialize();
    }

    public T Store<T>(T item)
    {
        using (var session = _store.OpenSession())
        {
            session.Store(item);
            session.SaveChanges();
        }
        return item;
    }
}

在我的测试项目中,我创建了两个虚假实现:

FakeMembershipProvider:

class FakeMembershipProvider : IMembershipProvider
{
    public string CreateUser(User newUser,string password)
    {
        CreatedUser = true;
        return newUser.Email == "email@example.com" ? Guid.NewGuid().ToString() : null;
    }

    public void AddToRole(User user,string rolename)
    {
        AddedToRole = true;
    }

    public bool AddedToRole;
    public bool CreatedUser;
}

和FakeRepository:

public class FakeRepository : IRepository
{
    public T Store<T>(T item)
    {
        StoreCalled = true;
        return item;
    }

    public bool StoreCalled;
}

测试大致如下:

public class UserManagementTests
{
    private readonly HelixManager _hm;
    private readonly IMembershipProvider _fakeMembershipProvider;
    private readonly IRepository _fakeRepository;

    public UserManagementTests()
    {
        _fakeMembershipProvider = new FakeMembershipProvider();
        _fakeRepository = new FakeRepository();
        _hm = new HelixManager(_fakeMembershipProvider,_fakeRepository);       
    }

    [TestMethod]
    public void CreateAdminReturnsValidAdminUser()
    {

        var newUser = new User
                           {
                               AvatarName = "fred",Email = "email@example.com",Forename = "Fred",Surname = "Jones"
                           };

        _hm.CreateAdmin(newUser,"password");

        Assert.IsNotNull(newUser.MemberId);
        Assert.AreEqual(UserType.Admin,newUser.Type);
    }

在我进一步了解这条线之前,我要问的是,这是正确的方法吗?或者有更好的方法吗?

我还计划有一个IntegrationTests项目,它将使用真正的数据库和真正的RavenDb实例来测试端到端.

干杯,

戴夫

解决方法

我认为这种做法没有错.您可以选择使用模拟工具( Rhino Mocks,Moq,NSubstitute)制作假货,而不是手工制作,但这实际上取决于个人喜好和个人使用工具的舒适程度.

你的测试结构清晰,基于状态断言(这是一件好事),你不要试图同时测试太多东西,这是一个常见的错误(即使是我们这些已经做了一段时间的人) .

如果你还没有看到它,我强烈推荐Roy Osherove’s Art of Unit Testing,它有很多关于单元测试的非常好的信息,包括保持测试清洁,如何处理代码不太可测试的区域等等.

我说保持卡车’:)

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读