Ошибка проверки атрибута [Обязательный] в тесте xUnit с Entity Framework Core

В этой библиотеке классов (ориентированной на .NET Standard 2.0 и .NET Framework 4.6.1) я выполняю проверку данных на уровне контекста данных, поскольку эти классы могут использоваться не веб-приложениями, поэтому я следую примеру из https://github.com/dotnet/efcore/issues/9662 в статическом вспомогательный класс:

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 (упрощенный):

public class Person
{
    [Required]
    public int Id { get; set; }
    [Required]
    public string FirstName { get; set; }
    [Required]
    public string LastName { get; set; }
    // other properties
}

Мой модульный тест (упрощенный):

[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;
    }
}

Метод класса обслуживания:

    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():

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 имеет один элемент (как и ожидалось)
  • entry.CurrentValues["FirstName"] - пустая строка (как и ожидалось)
  • Когда вы просматриваете его в списке наблюдения отладчика, entry.CurrentValues.Properties[5] показывает {Property: Person.FirstName (string) Required} (кажется правильным)
  • validationContext.Items показывает Count = 0 (подождите, что? Разве это не должно быть 1?)

Затем, когда я дойду до конца метода проверки, validationResults будет пустым, хотя там определенно должно быть что-то.

Согласно атрибуты аннотаций данных не работают в ядре asp net вам нужно AddDataAnnotations() в ServiceCollection, но это в ASP.NET MVC Core. Есть ли что-то подобное, что мне нужно сделать для моего приложения для модульного тестирования? Я что-то еще упускаю?

заранее спасибо


person howcheng    schedule 21.12.2020    source источник