【问题标题】:How to test my Exception extension method that uses DbEntityValidationException?如何测试使用 DbEntityValidationException 的异常扩展方法?
【发布时间】:2013-12-08 02:01:01
【问题描述】:

我希望我只是在看一些非常简单的东西……

我需要的答案必须提供使用 Moq 的测试,因为我无法访问我的个人 MSDN(专业)的 Fakes。只有高级版和终极版才能使用假货。单元测试必须能够在不访问任何外部资源的情况下运行。没有使用实体框架 DbContext 连接到 SQL 数据库。

public static string ToDetailedString(this Exception ex)
{
    var builder = new StringBuilder();
    AddExceptionToBuilder(builder, ex);
    return builder.ToString();
}

private static void AddExceptionToBuilder(StringBuilder builder, Exception ex)
{
    builder.Append(builder.Length > 0 ? "\r\n" + ex.Message : ex.Message);

    var validationException = ex as DbEntityValidationException;
    if (validationException != null)
    {
        foreach (var detail in validationException.EntityValidationErrors.SelectMany(error => error.ValidationErrors))
        {
            builder.Append("\r\n" + detail.PropertyName + " : " + detail.ErrorMessage);
        }
    }

    if (ex.InnerException != null)
    {
        AddExceptionToBuilder(builder, ex.InnerException);
    }
}

这就是测试如此困难的原因。它不像创建一个新的 DbEntityValidationException 那样简单,因为您必须传入一个 DbEntityValidationResult 列表。如果不提供 DbEntityEntry,则无法实例化 DbEntityValidationResult。我发现创建 DbEntityEntry 的唯一方法是从 DbContext.Entry() 中获取它。这意味着您必须具有需要访问数据库的有效 DbContext。

这是我能够编写的唯一代码,但它需要访问数据库。

/// <summary>
/// This test method must be ran against the database. I cannot figure out a way to create an entry without
/// a valid context to a real database?
/// </summary>
[TestMethod]
public void ToDetailStringForDbEntityValiditionException()
{
    if (!TestHelper.RunUnitTestAgainstDatabase)
    {
        return;
    }

    var errors = new List<DbValidationError>();
    errors.Add(new DbValidationError("Username", Constants.UsernameLengthError));

    var context = new EntityFrameworkRepository();
    var entry = context.Entry(new User());
    var results = new List<DbEntityValidationResult>();
    var result = new DbEntityValidationResult(entry, errors);
    results.Add(result);

    var exception = new DbEntityValidationException("Registration Failed.", results);

    var expected = "Registration Failed.\r\nUsername : " + Constants.UsernameLengthError;
    var actual = exception.ToDetailedString();

    Assert.AreEqual(expected, actual);
}

【问题讨论】:

  • 你有没有想过解决这个问题?我有一个类似的问题,我试图针对 DbEntityValidationException 进行测试,但由于内部构造函数我不能。 MS 开发人员似乎正在使用某种内部类进行自己的测试,但上帝禁止他们将其暴露给世界其他地方:github.com/Icehunter/entityframework/blob/master/test/…
  • 我仍然没有一个好的解决方案。现在我只是将异常转换为长字符串并确保消息详细信息包含“有效”信息。仍在寻找更好的解决方案,但现在我只有这些了。

标签: c# entity-framework


【解决方案1】:

这对我有用,使用我已经设置的实体模型和连接:

var context = new DbContext("name = JobManagerConnection");
var entry = context.Entry(new Models.JobManager.Job());
var errInner = new System.Data.Entity.Validation.DbValidationError("Test Property", "Test Message");
var lstErrInner = new List<System.Data.Entity.Validation.DbValidationError> { errInner };
var errOuter = new System.Data.Entity.Validation.DbEntityValidationResult (entry, lstErrInner);
var lstErrOuter = new List<System.Data.Entity.Validation.DbEntityValidationResult> { errOuter };
throw new System.Data.Entity.Validation.DbEntityValidationException("Test Data Exception", lstErrOuter);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-07-27
    • 1970-01-01
    • 2012-09-06
    • 1970-01-01
    • 2012-09-11
    • 1970-01-01
    • 1970-01-01
    • 2013-02-15
    相关资源
    最近更新 更多