首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >实体框架核心xUnit测试中[必需]属性失败的验证

实体框架核心xUnit测试中[必需]属性失败的验证
EN

Stack Overflow用户
提问于 2020-12-21 19:02:03
回答 1查看 366关注 0票数 1

在这个类库中(针对.NET标准2.0和.NET Framework4.6.1),我在数据上下文级别进行数据验证,因为这些类可能被非web应用程序使用,所以我在静态帮助器类中遵循https://github.com/dotnet/efcore/issues/9662的示例:

代码语言:javascript
复制
internal static ICollection<ValidationResult> ValidateChanges(DbContext context)
{
    var modifiedEntries = context.ChangeTracker.Entries()
                                 .Where(x => x.State == EntityState.Added || 
                                             x.State == EntityState.Modified);
    List<ValidationResult> validationResults = new List<ValidationResult>();

    foreach (var entry in modifiedEntries)
    {
        var validationContext = new ValidationContext(entry);
        Validator.TryValidateObject(entry, validationContext, validationResults, true);
    }

    return validationResults;
}

我的POCO (简化):

代码语言:javascript
复制
public class Person
{
    [Required]
    public int Id { get; set; }
    [Required]
    public string FirstName { get; set; }
    [Required]
    public string LastName { get; set; }
    // other properties
}

我的单元测试(简化):

代码语言:javascript
复制
[Fact]
public void TestDataValidation()
{
    IPersonService svc = _container.Resolve<IPersonService>();
    Person p = svc.Get(1);
    string origValue = p.FirstName;
    p.FirstName = string.Empty;

    try
    {
        Assert.Throws<ValidationException>(() => svc.Update(p, p.Id));
    }
    catch (Xunit.Sdk.XunitException) // ValidationException not thrown
    {
        // restore original value

        throw;
    }
}

服务类方法:

代码语言:javascript
复制
    public virtual TEntity Update(TEntity entity, TKey key)
    {
        if (entity == null)
            throw new ArgumentNullException(nameof(entity));

        ((IDatabaseContext)Context).BeginTransaction();
        TEntity dbEntity = Get(key);
        Context.Entry(dbEntity).CurrentValues.SetValues(entity);
        ((IDatabaseContext)Context).Commit();
        return entity;
    }

Commit()方法:

代码语言:javascript
复制
public abstract class DatabaseContext<TContext> : DbContext, IDatabaseContext
    where TContext : DbContext
{
    public void Commit()
    {
        ICollection<ValidationResult> validationResults = DbContextHelper.ValidateChanges(this);
        if (validationResults.Count > 0)
        {
            foreach (ValidationResult validationResult in validationResults)
            {
                string message = string.Format("{0}: {1}", string.Join(", ", validationResult.MemberNames.ToArray()), validationResult.ErrorMessage);
                throw new ValidationException(message);
            }
        }
        base.Commit();
    }
}

当我执行测试时,验证完成失败。当我在验证方法的foreach循环中间放置一个断点时,我看到的是:

  • modifiedEntries有一个条目(因为expected)
  • entry.CurrentValues["FirstName"]是一个空字符串)(当expected)
  • When在调试器监视列表中查看它时,entry.CurrentValues.Properties[5]显示{Property: Person.FirstName (string) Required} (似乎right)
  • validationContext.Items显示Count = 0 )(等等,什么?这不应该是

吗?

然后,当我到达验证方法的末尾时,validationResults是空的,尽管其中肯定有一些东西。

根据Data annotations attributes not working in asp net core,您需要在ServiceCollection上使用AddDataAnnotations(),但这是在ASP.NET MVC核心中实现的。对于我的单元测试应用程序,有类似的事情需要做吗?我还有什么遗漏吗?

提前感谢

EN

回答 1

Stack Overflow用户

发布于 2021-10-22 22:33:57

你可以试试这样的东西

代码语言:javascript
复制
//Assert
foreach (var item in ValidateModel(itemToCreate))
{
    if(!string.IsNullOrEmpty(item.ErrorMessage)) throw new ValidationException(item.ErrorMessage); 
}

/////

private static IList<ValidationResult> ValidateModel(object model)
{
    var validationResults = new List<ValidationResult>();
    var ctx = new ValidationContext(model, null, null);
    Validator.TryValidateObject(model, ctx, validationResults, true);
    return validationResults;
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/65398511

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档