如何为依赖于DbEntityEntry的对象创建单元测试

时间:2014-10-28 16:18:34

标签: c# .net entity-framework unit-testing mstest

我有以下帮助器方法,它将验证消息从DbEntityValidationException中取出。我们需要这个,因为默认情况下,验证的细节不会添加到Exception中。

public static string LogMessageDbEntityValidationException(DbEntityValidationException ex)
{
   StringBuilder error = new StringBuilder();

   error.AppendLine("Validation Error details for DbEntityValidationException throw: ");

   foreach (var validationErrors in ex.EntityValidationErrors)
   {
      foreach (var validationError in validationErrors.ValidationErrors)
      {
         error.AppendLine(string.Format("Property: {0} , Error: {1}", 
                          validationError.PropertyName, validationError.ErrorMessage));
      }
   }

   return error.ToString();
}

我遇到了尝试创建单元测试的问题,特别是我无法创建DbEntityValidationResult,因为它需要一个DbEntityEntry实例,它没有公共构造函数。

这是单元测试中断,它在创建DbEntityEntry时失败:

public void LogMessageDbEntityValidationExceptionTest()
{
  string errorMessage = "Unit Test Error Message";
  string expected = "Not valid data.";
  List<DbEntityValidationResult> entityValidationResults = new List<DbEntityValidationResult>();
  List<DbValidationError> errorList = new List<DbValidationError>();
  DbEntityValidationException ex;

  errorList.Add(new DbValidationError("TestProperty", expected));

  entityValidationResults.Add(new DbEntityValidationResult(new System.Data.Entity.Infrastructure.DbEntityEntry(), errorList));

  ex = new DbEntityValidationException(errorMessage, entityValidationResults);
  string actual = Common.LogMessageDbEntityValidationException(ex);

  Assert.IsTrue(actual.Contains(expected));
}

注意,DbEntityEntry没有实现接口,所以我不能使用mock / fake。

1 个答案:

答案 0 :(得分:1)

像Moq这样的一些模拟框架可以进行方法重定向,允许您在没有接口的情况下模拟类。做其类似的 http://www.codenutz.com/unit-testing-mocking-base-class-methods-with-moq/

据说这不是一个好的编程实践,因为你将使你的测试代码永远依赖于该框架,你会失去单元测试的一些设计优势。

你可以做的是编写一个代理类来包装你的untestable对象并在其上添加一个接口然后你每次使用普通类时都使用代理类。