这是我的班级:
public class AuditInfo
{
public String ActionDescription { get; set; }
public String ActionWho { get; set; }
public BasicProjectProfile Project { get; set; }
public AuditInfo ()
{ }
public void SaveInfo ()
{
using (CIHEntities _dbContext = new CIHEntities())
{
AuditInfoEntity aie = new AuditInfoEntity();
aie.ActionDescription = this.ActionDescription;
aie.ActionWhen = DateTime.Now;
if (this.ActionWho != null)
{
aie.ActionWho = this.ActionWho;
}
else
{
aie.ActionWho = "Not Specified";
}
aie.ProjectAssoc = _dbContext.ProjectEntity
.Where(r => r.Id == this.Project.Id)
.First();
_dbContext.SaveChanges();
}
}
}
CIHEntities
是一个实体框架数据库。
我想对SaveInfo方法进行单元测试,但实际上不应该保存到数据库中。怎么能这样做?
由于
埃里克
答案 0 :(得分:0)
Given : that Id don't know what is the interface of CIHEntities
When : Unit Test is required for AuditInfo.SaveInfo
Then : inject the interface of CIHEntities from constructor of AuditInfo
Then : create a mock of CIHEntities from its interface and use it for Unit Test
请模仿期望并验证使用模拟库(例如Moq
)调用SaveChanges答案 1 :(得分:0)
使用Repository模式并将保存enity的责任转移到Repository:
public class AuditInfo
{
public String ActionDescription { get; set; }
public String ActionWho { get; set; }
public BasicProjectProfile Project { get; set; }
}
为您的存储库编写一个接口:
public interface IRepository
{
void Save();
}
然后你的实施:
public RealRepository : IRepository
{
public void SaveInfo ()
{
using (CIHEntities _dbContext = new CIHEntities())
{
AuditInfoEntity aie = new AuditInfoEntity();
aie.ActionDescription = this.ActionDescription;
aie.ActionWhen = DateTime.Now;
if (this.ActionWho != null)
{
aie.ActionWho = this.ActionWho;
}
else
{
aie.ActionWho = "Not Specified";
}
aie.ProjectAssoc = _dbContext.ProjectEntity
.Where(r => r.Id == this.Project.Id)
.First();
_dbContext.SaveChanges();
}
}
}
然后使您的客户端代码将存储库作为参数将是这样的
public class MyClient{
IRepository _repository;
public MyClient(){
_repository = new RealRepository();
}
public MyClient(IRepository repository)
{
_repository = repository;
}
public void Main(){
AuditInfo entity = new AuditInfo();
//do whatever you want
_repository.Save();
}
}
您的真实应用程序可以使用默认构造函数,它将使用RealRepository,而单元测试可以传递一个不与数据库对话的Fake Repository实现(或者甚至更好地使用像Moq这样的Mocking框架)。
这是基本概念,您可以改进它以拥有通用存储库,使用UoW模式...您可以在这篇msdn文章中阅读更多相关信息:Testability and EF
答案 2 :(得分:0)
使用TransactionScope。除非您实际提交更改,否则不会将其添加到数据库中。这就是我在单元测试中使用的,它完美无缺。
要使用它,您必须添加对System.Transactions的引用,之后您可能会收到一些Windows错误。如果我没记错的话,你必须启动一些Windows服务。但是,当你走得那么远的时候谷歌吧。