我没有使用实体框架,我也不是100%确定我知道这里发生的事情的全部范围,但是您需要做的是在具有接口的实体框架代码周围放置一个包装器,然后使用模拟框架假装您在实际上没有调用数据库时调用数据库。我会给你一个大概的想法,但是你必须把它应用到实体框架中,因为我不知道细节。
public interface IShareSpaceGateway {
IEnumerable<ShareSpace> GetSharedSpaces(string spaceToShare, string emailToShareIt);
}
public class ShareSpaceGatewayEF: IShareSpaceGateway
{
// MySpacesShared should be included up here, not sure what type it is
public IEnumerable<ShareSpace> GetSharedSpaces(string spaceToShare, string emailToShareIt)
{
if (!this.MySpacesShared.IsLoaded)
this.MySpacesShared.Load();
return this.MySpacesShared.Any(s => (s.EmailAddress == emailToShareIt)
& (s.SpaceName == spaceToShare));
}
}
您可以在isharedspacegateway中使用任何有意义的方法。其目的是减少代码重复。
现在,您希望能够注入对IShareSpaceGateway的新依赖项。使用依赖注入的最佳方法是使用DI容器,如Castle Windsor、结构图、Ninject或Unity。我假设你的代码在这里是什么样子的:
public class Account
{
private ISharedSpaceGateway _sharedSpaceGateway;
public Account(ISharedSpaceGateway sharedSpaceGateway)
{
_sharedSpaceGateway = sharedSpaceGateway;
}
public int ID { get; set; }
public string Key1 { get; set; }
public string Key2 { get; set; }
public string AccountName { get; set; }
public void ShareSpace(string spaceToShare,string emailToShareIt)
{
SharedSpace shareSpace = new SharedSpace();
shareSpace.InvitationCode = Guid.NewGuid().ToString("N");
shareSpace.DateSharedStarted = DateTime.Now;
shareSpace.Expiration = DateTime.Now.AddYears(DefaultShareExpirationInYears);
shareSpace.Active = true;
shareSpace.SpaceName = spaceToShare;
shareSpace.EmailAddress = emailToShareIt;
var sharedSpaces = sharedSpaceGateway.GetSharedSpaces(spaceToShare, emailToShareIt);
if(sharedSpaces.Count() > 0)
throw new InvalidOperationException("Cannot share the a space with a user twice.");
this.MySpacesShared.Add(shareSpace);
}
}
现在,在单元测试中,您希望使用模拟框架(如moq)或Rhinomocks来设置测试。在您的测试中,您不想使用sharedspacegateway的实际实现,而是希望传入一个假的实现。此示例使用犀牛模型
public class TestFixture{
private ISharedSpaceGateway gateway;
[TestInitialize()]
public void MyTestInitialize()
{
gateway = MockRepository.CreateMock<ISharedSpaceGateway>();
gateway.Expect(g => g.GetSharedSpaces("spaceName", "user1@domain.com"))
.Return(new SharedSpace()); // whatever you want to return from the fake call
user = new User()
{
Active = true,
Name = "Main User",
UserID = 1,
EmailAddress = "user1@userdomain.com",
OpenID = Guid.NewGuid().ToString()
};
account = new Account(gateway) // inject the fake object
{
Key1 = "test1",
Key2 = "test2",
AccountName = "Brief Account Description",
ID = 1,
Owner = user
};
}
[TestMethod]
public void Cannot_Share_SameSpace_with_same_userEmail_Twice()
{
account.ShareSpace("spaceName", "user1@domain.com");
try
{
account.ShareSpace("spaceName", "user1@domain.com");
Assert.Fail("Should throw exception when same space is shared with same user.");
}
catch (InvalidOperationException)
{ /* Expected */ }
Assert.AreEqual(1, account.MySpacesShared.Count);
Assert.AreSame(null, account.MySpacesShared.First().InvitedUser);
gateway.VerifyAllExpectations();
}
使用DI框架和模拟框架涉及很多,但是这些概念使您的代码更易于测试。