我有一個連接到這樣的用戶信息庫的自定義成員提供:單元測試我自定義的成員提供
public class MyMembershipProvider : MembershipProvider {
[Inject]
public IUserRepository UserRepository { get; set; }
...
//Required membership methods
}
我使用ninject我的DI。現在我想測試提供程序,並注入一個模擬用戶存儲庫以允許我執行此操作。因此,像:
...
IList<User> users = new List<User> {
new User { Email="[email protected]",
UserName="[email protected]",
Password="test"
}
};
var mock = new Mock<IUserRepository>();
mock.Setup(mr => mr.FindByUsername(
It.IsAny<string>())).Returns((string s) => users.Where(
x => x.UserName.Equals(s,StringComparison.OrdinalIgnoreCase)).Single());
...
而且這裏是我不能肯定如何着手,如何讓我的嘲笑庫注入到我的供應商,這樣,當一個單元測試,將調用提供者使用這種模擬庫?
我在這裏問正確的問題嗎?
編輯 - 我的最終解決方案
對於什麼是值得我用從模擬到使用InMemory庫,以保持狀態,這樣的供應商將正確測試某些功能搬走。現在我只用這個來測試像我的提供者這樣的東西。我結束了:
通用InMemoryRepository:
class InMemoryRepository<TEntity> : IRepository<TEntity> where TEntity : class {
private int _incrementer = 0;
public Dictionary<int, TEntity> List = new Dictionary<int, TEntity>();
public string IDPropertyName {get; set;}
public void Create(TEntity entity) {
_incrementer++;
entity.GetType().GetProperties().First(p => p.Name == IDPropertyName).SetValue(entity, _incrementer, null);
List.Add(_incrementer,entity);
}
public TEntity GetById(int id) {
return List[id];
}
public void Delete(TEntity entity) {
var key = (int)entity.GetType().GetProperties().First(p => p.Name == IDPropertyName).GetValue(entity, null);
List.Remove(key);
}
public void Update(TEntity entity) {
var key = (int)entity.GetType().GetProperties().First(p => p.Name == IDPropertyName).GetValue(entity, null);
List[key] = entity;
}
}
然後我的實際用戶信息庫 - 我沒有通用的ID字段這就是爲什麼我使用的IDPropertyName變量:
class InMemoryUserRepository : InMemoryRepository<User>, IUserRepository {
public InMemoryUserRepository() {
this.IDPropertyName = "UserID";
}
public IQueryable<User> Users {
get { return List.Select(x => x.Value).AsQueryable(); }
}
public User FindByUsername(string username) {
int key = List.SingleOrDefault(x=>x.Value.UserName.Equals(username, StringComparison.OrdinalIgnoreCase)).Key;
return List[key];
}
}
我會員測試基類:
[TestClass]
public class MyMembershipProviderTestsBaseClass : IntegrationTestsBase {
protected MyMembershipProvider _provider;
protected NameValueCollection _config;
protected MembershipCreateStatus _status = new MembershipCreateStatus();
[TestInitialize]
public override void Initialize() {
base.Initialize();
// setup the membership provider
_provider = new MyMembershipProvider();
MembershipSection section = (MembershipSection) ConfigurationManager.GetSection("system.web/membership");
NameValueCollection collection = section.Providers["MyMembershipProvider"].Parameters;
_provider.Initialize(null, collection);
_status = new MembershipCreateStatus();
}
[TestCleanup]
public override void TestCleanup() {
base.TestCleanup();
}
}
然後我的測試:
[TestMethod]
public void Membership_CreateUser() {
_provider.UserRepository = new InMemoryUserRepository();
_provider.CreateUser(_email, out _status);
Assert.AreEqual(MembershipCreateStatus.Success, _status);
}
這個答案提供了靈感:https://stackoverflow.com/a/13073558/1803682
我很專注於讓它注入我並沒有停下來考慮明顯。無論如何,最終不得不放棄嘲笑 - 並創建內存中的存儲庫,以保留狀態並測試提供者。謝謝! – Matthew