JonPSmith / EfCore.TestSupport

Tools for helping in unit testing applications that use Entity Framework Core
https://www.thereformedprogrammer.net/new-features-for-unit-testing-your-entity-framework-core-5-code/
Other
352 stars 53 forks source link

Comparison always fails for default values on BIT NOT NULL (boolean) fields #28

Closed davisnw closed 4 years ago

davisnw commented 4 years ago

Tested using EfCore.TestSupport nuget package 3.1.0

Consider a table

CREATE TABLE [dbo].[Foos]
(
    [Id] [int] IDENTITY(1,1) NOT NULL,
    [IsFoosable] [bit] NOT NULL DEFAULT 1,
    CONSTRAINT [PK_Foos] PRIMARY KEY CLUSTERED (Id)
)

Consider an entity

public class Foo
{
    [Key]
    public int Id { get; set; }

    public bool IsFoosable { get; set; }
}

Consider a context

public class FooContext : DbContext
{
    public DbSet<Foo> Foos { get; set; }

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

        modelBuilder.Entity<Foo>()
            .Property(x => x.IsFoosable)
            .HasDefaultValue(true);

    }
}

Then the test

            //--------- Arrange ---------//
            string connectionString = ...;

            var config = new CompareEfSqlConfig();

            var comparer = new CompareEfSql(config);

            using (var fooContext = CreateFooContext())
            {
                //--------- Act ---------//
                var hasErrors = comparer.CompareEfWithDb(connectionString, fooContext);

                //--------- Assert ---------//
                Assert.False(hasErrors, comparer.GetAllErrors);
            }

Will fail with:

Message: 
    DIFFERENT: Foo->Property 'IsFoosable', default value sql. Expected = True, found = 1

If the context instead does:

   ...
        modelBuilder.Entity<Foo>()
            .Property(x => x.IsFoosable)
            .HasDefaultValue(1);
   ...

The failure is still

Message: 
    DIFFERENT: Foo->Property 'IsFoosable', default value sql. Expected = True, found = 1

So there appears to be no way to configure a default value for boolean / bit not null that EfCore.TestSupport will consider to be comparable.

JonPSmith commented 4 years ago

Hi @davisnw,

Yep, the EfSchemaCompare tool has limitations, as found in the EfSchemaCompare ->Limitations page. I could have left the DefaultValueSql test out, but then you wouldn't know that EfSchemaCompare didn't check everything.

The EfSchemaCompare ->Limitations page has this link to an example of how to ignore the DefaultValueSql test.