在EF 7.0中使用数据注释或流畅的api验证实体(内存中)

par*_*man 6 unit-testing mstest in-memory-database data-annotations entity-framework-core

我无法通过内存提供程序验证和测试我的数据库.例如,我将这些属性设置为必需:

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
}
Run Code Online (Sandbox Code Playgroud)

这是我的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));


    }
Run Code Online (Sandbox Code Playgroud)

这是我的单元测试:

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

        }
    }
Run Code Online (Sandbox Code Playgroud)

但是单元测试方法总是返回1并且通过,同时LogRequest的空对象不能保存到数据库中!如何确定单元测试的非null属性?实际上,我如何强制执行单元测试以反映验证策略?

更新:

基于此linke: 实体框架核心问题

我问过,我得到了回应:

除了内部一致性所需的内容之外,EF Core不会对实体进行任何验证.验证是可以在EF中完成的,但经验表明它不是对许多开发人员有用的东西,因为它通常不能取代客户端验证或数据库验证,还有其他地方可以更有效地进行验证.

超出EF到数据库,内存数据库当前在保存属性值时不验证可空性(即必需性).我将把这个问题保持开放,以便我们可以作为一个团队讨论这是否是我们应该添加的内容.

此外,如果使用内存数据库测试intent作为关系数据库的近似值,那么您可能需要考虑在内存模式下使用SQLite.有关 更多信息,请参阅 https://docs.microsoft.com/en-us/ef/core/miscellaneous/testing/index.