在EF 7.0中使用數據註釋或流暢的api驗證實體(內存中)

data-annotations entity-framework-core in-memory-database mstest unit-testing

我無法通過內存提供程序驗證和測試我的數據庫。例如,我將這些屬性設置為必需:

public abstract class Log
{
    #region Properties
    public Guid Id { get; set; }
    [Required]
    public string ClientIp { get; set; }
    [Required]
    public string Application { get; set; }
    [Required]
    public string Host { get; set; }
    [Required]
    public string Path { get; set; }
    [Required]
    public string Method { get; set; }
    [Required]
    public string User { get; set; }
    [Required]
    public string Date { get; set; }
    #endregion
}

這是我的DBContext:

public class ApplicationDbContext : IdentityDbContext<ApplicationUsers, Role, Guid>, IUnitOfWork
{
    private readonly IConfigurationRoot _configuration;

    public ApplicationDbContext(IConfigurationRoot configuration)
    {
        _configuration = configuration;
    }

    protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    {
        var useInMemoryDatabase = _configuration[key: "UseInMemoryDatabase"].Equals(value: "true",
            comparisonType: StringComparison.OrdinalIgnoreCase);
        if (useInMemoryDatabase)
            optionsBuilder.UseInMemoryDatabase();
        else
            optionsBuilder.UseSqlServer(
                connectionString: _configuration[key: "ConnectionStrings:ApplicationDbContextConnection"]
                , sqlServerOptionsAction: serverDbContextOptionsBuilder =>
                {
                    var minutes = (int) TimeSpan.FromMinutes(3).TotalSeconds;
                    serverDbContextOptionsBuilder.CommandTimeout(commandTimeout: minutes);
                });
    }

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        base.OnModelCreating(modelBuilder);

        modelBuilder.Entity<Log>()
            .HasKey(c => c.Id);
        modelBuilder.Entity<Log>()
            .HasDiscriminator<int>(name: "Type")
            .HasValue<LogRequest>(value: Convert.ToInt32(value: LogLevel.Information))
            .HasValue<LogError>(value: Convert.ToInt32(value: LogLevel.Error));


    }

這是我的單元測試:

[TestClass]
public class LogRepositoryTest
{


  private readonly IServiceProvider _serviceProvider;
    public LogRepositoryTest()
    {
        var services = new ServiceCollection();
        services.AddScoped<IUnitOfWork, ApplicationDbContext>();
        services.AddScoped<ILogRepository, LogRepository>();
        services.AddSingleton(provider => new ConfigurationBuilder()
            .AddInMemoryCollection(initialData: new[]
            {
                new KeyValuePair<string, string>(key: "UseInMemoryDatabase", value: "true"),

            })
            .Build());
         services.AddEntityFrameworkInMemoryDatabase().AddDbContext<ApplicationDbContext>(ServiceLifetime.Scoped);
        _serviceProvider = services.BuildServiceProvider();
    }
    [TestMethod]
    public async Task Verify_SaveRequestLog()
    {
        using (var serviceScope = _serviceProvider.GetRequiredService<IServiceScopeFactory>().CreateScope())
        {
            using (var context = serviceScope.ServiceProvider.GetRequiredService<IUnitOfWork>())
            {
                context.Set<Log>().Add(new LogRequest());
                var result =await context.SaveAllChangesAsync();
                Assert.AreEqual(1, result);
            }

        }
    }

但是單元測試方法總是返回1並且通過,同時LogRequest的空對像不能保存到數據庫中!如何確定單元測試的非null屬性?實際上,我如何強制執行單元測試以反映驗證策略?

更新:

基於此linke: 實體框架核心問題

我問過,我得到了回應:

除了內部一致性所需的內容之外,EF Core不會對實體進行任何驗證。驗證是可以在EF中完成的,但經驗表明它不是對許多開發人員有用的東西,因為它通常不能取代客戶端驗證或數據庫驗證,還有其他地方可以更有效地進行驗證。

超出EF到數據庫,內存數據庫當前在保存屬性值時不驗證可空性(即必需性)。我將把這個問題保持開放,以便我們可以作為一個團隊討論這是否是我們應該添加的內容。

此外,如果使用內存數據庫測試intent作為關係數據庫的近似值,那麼您可能需要考慮在內存模式下使用SQLite。有關更多信息,請參閱https://docs.microsoft.com/en-us/ef/core/miscellaneous/testing/index

一般承認的答案

基於此linke: 實體框架核心問題

我問,我得到了答案:

class MyContext : DbContext
{
public override int SaveChanges()
{
    var entities = from e in ChangeTracker.Entries()
                   where e.State == EntityState.Added
                       || e.State == EntityState.Modified
                   select e.Entity;
    foreach (var entity in entities)
    {
        var validationContext = new ValidationContext(entity);
        Validator.ValidateObject(entity, validationContext);
    }

    return base.SaveChanges();
}
}


Related

許可下: CC-BY-SA with attribution
不隸屬於 Stack Overflow
許可下: CC-BY-SA with attribution
不隸屬於 Stack Overflow