Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to unit test EF core 3 view with no key in-memory?

I'm playing around with EF Core 3 and writing some unit tests and don't seem to be able to setup test data for a view.

When I'm trying to save, I get the error:

Unable to track an instance of type because it does not have a primary key. Only entity types with primary keys may be tracked

public class EFContext : DbContext
{
    public DbSet<ViewItem> ViewItems { get; set; }

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        modelBuilder.Entity<ViewItem>().HasNoKey().ToView("vTestView");
    }
}

using (EFContext efContext = new EFContext())
{
    efContext.ViewItems.Add(new ViewItem
    {
        Name = "This is test item #1"
    });

    efContext.SaveChanges();
}
like image 561
user3953989 Avatar asked Oct 04 '19 13:10

user3953989


1 Answers

Workaround: IsInMemory()

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    modelBuilder.Entity<ViewItem>(entity =>
    {
        if (!Database.IsInMemory())
        {
            entity.HasNoKey();
            entity.ToView("vTestView");
        }
        else
        {
            entity.HasKey(e => e.Name);
        }
    });
}

UPDATE: To preserve the behavior of the Properties Under Test between Test Time and Runtime, you could add a key property that (by convention) you only use during testing, and you configure the model to ignore the property when you are not in testing:

public class ViewItem 
{
    public int TestOnlyKey { get; set; }
    public string Name { get; set; }
}
public class EFContext : DbContext
{
    public DbSet<ViewItem> ViewItems { get; set; }
    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        modelBuilder.Entity<ViewItem>(entity =>
        {
            if (!Database.IsInMemory())
            {
                entity.HasNoKey();
                entity.Ignore(e => e.TestOnlyKey);
                entity.ToView("vTestView");
            }
            else
            {
                entity.HasKey(e => e.TestOnlyKey);
            }
        });
    }
}
like image 164
Sam Avatar answered Sep 23 '22 01:09

Sam