Can this TestDBSet class from EF 6 be adapted to work with EF Core?

.net-core c# dependency-injection entity-framework-core mocking

Question

I am trying to write my own test doubles for mock testing Entity Framework core by following this tutorial for EF 6:

https://docs.microsoft.com/en-us/ef/ef6/fundamentals/testing/writing-test-doubles

The tutorial comes stuck on the TestDbSet class, which should provide an in-memory implementation of DbSet. However, most of the members are not compatible with EF Core:

public class TestDbSet<TEntity> : DbSet<TEntity>, IQueryable, IEnumerable<TEntity>, IDbAsyncEnumerable<TEntity>
    where TEntity : class
{
    ObservableCollection<TEntity> _data;
    IQueryable _query;

    public TestDbSet()
    {
        _data = new ObservableCollection<TEntity>();
        _query = _data.AsQueryable();
    }

    public override TEntity Add(TEntity item)
    {
        _data.Add(item);
        return item;
    }

    public override TEntity Remove(TEntity item)
    {
        _data.Remove(item);
        return item;
    }

    public override TEntity Attach(TEntity item)
    {
        _data.Add(item);
        return item;
    }

    public override TEntity Create()
    {
        return Activator.CreateInstance<TEntity>();
    }

    public override TDerivedEntity Create<TDerivedEntity>()
    {
        return Activator.CreateInstance<TDerivedEntity>();
    }

    public override ObservableCollection<TEntity> Local
    {
        get { return _data; }
    }

    Type IQueryable.ElementType
    {
        get { return _query.ElementType; }
    }

    Expression IQueryable.Expression
    {
        get { return _query.Expression; }
    }

    IQueryProvider IQueryable.Provider
    {
        get { return new TestDbAsyncQueryProvider<TEntity>(_query.Provider); }
    }

    System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
    {
        return _data.GetEnumerator();
    }

    IEnumerator<TEntity> IEnumerable<TEntity>.GetEnumerator()
    {
        return _data.GetEnumerator();
    }

    IDbAsyncEnumerator<TEntity> IDbAsyncEnumerable<TEntity>.GetAsyncEnumerator()
    {
        return new TestDbAsyncEnumerator<TEntity>(_data.GetEnumerator());
    }
}

The error that occurs for the Add, Attach, Remove and Create methods is the same for all four:

'TestDbSet<TEntity>.Add(TEntity)': return type must be 'EntityEntry<TEntity>' to match overridden member 'DbSet<TEntity>.Add(TEntity)

Would anyone be able to explain if I can convert <TEntity> to EntityEntry<TEntity> or if there is a better way to work around the problem? Many thanks

1
0
2/18/2019 4:10:16 PM

Popular Answer

@Edward your solution worked brilliantly, by returning null the tutorial is now compatible with EF core at least for my tests, thanks for the hint.

some modifications in TestContext: - using Microsoft.EntityFrameworkCore.Query.Internal; - using Microsoft.EntityFrameworkCore.ChangeTracking; - change IDbAsyncEnumaerable and IDbAsyncEnumerator to IAsyncEnumerable and IAsyncEnumerator - add, remove and attach methods: change return type from TEntity to EntityEntry and change last statement in each method to return null; - some other methods will show compile error, just delete them.

0
3/2/2020 3:32:04 PM


Related Questions





Related

Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow