Я запускаю веб-приложение, которое будет использовать службы членства asp.net (с серверным сервером sql) для наблюдения за пользователями и 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, который будет использовать настоящий db и настоящий экземпляр RavenDb для сквозного тестирования.
Cheers,
Дэйв