EF inMemory提供程序在字段设置为required时错误地接受空条目

时间:2017-10-02 13:43:35

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

这是我的集成测试代码:

[Fact(DisplayName = "Should only add AssetType when Name Provided")]
public async Task Test4()
{
    using (var context = GetContext()) {

        var listAssetTypes = await context.AssetType.ToListAsync();

        Assert.Equal(0, listAssetTypes.Count);

        var goodAssetType = new AssetType { Name = "1st Item" };
        context.Add(goodAssetType);
        await context.SaveChangesAsync();
        listAssetTypes = await context.AssetType.ToListAsync();

        Assert.Equal(1, listAssetTypes.Count);

        var badAssetType = new AssetType {};
        context.Add(badAssetType);
        await context.SaveChangesAsync();
        listAssetTypes = await context.AssetType.ToListAsync();

        Assert.Equal(1, listAssetTypes.Count);
    }
}

前两个断言的传球。第三个失败,实际是2,如果我调试我可以看到已经分配了新的ID并且名称设置为null。

这是我的上下文方法:

private WorldContext GetContext()
{
    var builder = new ConfigurationBuilder();
    var config = builder.Build();
    var options = new DbContextOptionsBuilder<WorldContext>()
        .UseInMemoryDatabase(Guid.NewGuid().ToString()).Options;
    var context = new WorldContext(config, options);
    return context;
}

我的模特:

public class AssetType
{
    [DatabaseGenerated(databaseGeneratedOption: DatabaseGeneratedOption.Identity)]
    [Key]
    public int AssetTypeId { get; set; }
    [Required]
    public string Name { get; set; }
}

1 个答案:

答案 0 :(得分:3)

请注意,InMemory提供程序不是生产就绪的关系数据库提供程序,仅用于协助进行集成测试。

它不会(有必要)强制执行数据的一致性,或者确保像真正的数据库提供程序那样实现约束。

这是明确记录和预期的行为,请阅读文档&#34; Test with InMemory&#34;

  

InMemory不是关系数据库

     

EF核心数据库提供商   不一定是关系数据库。 InMemory旨在成为一个   用于测试的通用数据库,并非旨在模仿a   关系数据库。

     

这方面的一些例子包括:

     
      
  • InMemory允许您保存违反参照完整性的数据   关系数据库中的约束。
  •   
  • 如果对模型中的属性使用DefaultValueSql(string),则为a   关系数据库API,在运行时无效   在记忆中。提示
  •   
     

对于许多测试目的,这些差异无关紧要。但是,如果   你想测试一些表现得更像真实的东西   关系数据库,然后考虑使用SQLite内存模式。

话虽如此:如果您确实需要验证约束,请遵循文档的建议,并在内存数据库中使用Sqlite代替进行集成测试。