0

这是我的课:

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 方法进行单元测试,但它实际上不应该保存到数据库中。如何才能做到这一点?

谢谢

埃里克

4

3 回答 3

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

于 2012-10-25T22:26:09.680 回答
0

使用存储库模式并将保存实体的责任转移到存储库:

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 文章中阅读更多信息:可测试性和 EF

于 2012-10-25T22:30:24.730 回答
0

使用TransactionScope。除非您实际提交更改,否则不会将其添加到数据库中。这就是我在单元测试中使用的,它完美地工作。

要使用它,您必须添加对 System.Transactions 的引用,然后您可能会收到一些 Windows 错误。如果我没记错的话,你必须启动一些 Windows 服务。但是,当你走到那一步时,谷歌它。

于 2012-10-26T12:40:02.257 回答