r3plica
r3plica

Reputation: 13367

NBuilder and DbContext invalid cast issue

I am really new to NBuilder, but it looks awesome so I thought I would have a go. I have a DatabaseContext which just inherits from DbContext like this:

public class DatabaseContext : DbContext

Now, I have created a service that queries the DatabaseContext like this:

public async Task<List<Strategy>> Handle(StrategyList query, CancellationToken cancellationToken)
{
    return _databaseContext.Strategies.ToList();
}

And now I want to make a test. I set this Context up like this:

public class StrategyListContext
{ 
    public readonly DatabaseContext DatabaseContext;

    private StrategyListContext()
    {
        DatabaseContext = CreateDatabaseContext();
    }

    private DatabaseContext CreateDatabaseContext()
    {
        var dbContext = Substitute.For<DatabaseContext>();

        var items = Builder<Strategy>.CreateListOfSize(10).Build();
        dbContext.Strategies.ToList().Returns(items);

        return dbContext;
    }

    public static StrategyListContext GivenServices() => new StrategyListContext();

    public StrategyListHandler WhenCreateHandler() => new StrategyListHandler(DatabaseContext);
}

The most important part is the CreateDatabaseContext method. It is like this:

private DatabaseContext CreateDatabaseContext()
{
    var dbContext = Substitute.For<DatabaseContext>();

    var items = Builder<Strategy>.CreateListOfSize(10).Build();
    dbContext.Strategies.ToList().Returns(items);

    return dbContext;
}

But when I run the test, I get this error:

System.InvalidCastException : Unable to cast object of type 'Castle.Proxies.ObjectProxy' to type 'Microsoft.EntityFrameworkCore.Metadata.Internal.Model'.

Does anyone know what I can do to get this working?


So I found this question: How do I mock DbContext using NSubstitute and then add/remove data

And I have changed my method to this:

private DatabaseContext CreateDatabaseContext()
{
    var dbContext = Substitute.For<DatabaseContext>();

    var items = Builder<Strategy>.CreateListOfSize(10).Build().AsQueryable();
    var dbSet = Substitute.For<DbSet<Strategy>, IQueryable<Strategy>>();
    ((IQueryable<Strategy>)dbSet).Provider.Returns(items.Provider);
    ((IQueryable<Strategy>)dbSet).Expression.Returns(items.Expression);
    ((IQueryable<Strategy>)dbSet).ElementType.Returns(items.ElementType);
    ((IQueryable<Strategy>)dbSet).GetEnumerator().Returns(items.GetEnumerator());
    dbContext.Set<Strategy>().Returns(dbSet);

    return dbContext;
}

But I still get the same error....

Upvotes: 0

Views: 100

Answers (1)

r3plica
r3plica

Reputation: 13367

The second solution was soooo close, it was simply this:

private static DatabaseContext CreateDatabaseContext()
{
    var dbContext = Substitute.For<DatabaseContext>();

    var items = Builder<Hall>.CreateListOfSize(10).Build().AsQueryable();
    var dbSet = Substitute.For<DbSet<Hall>, IQueryable<Hall>>();
    ((IQueryable<Hall>)dbSet).Provider.Returns(items.Provider);
    ((IQueryable<Hall>)dbSet).Expression.Returns(items.Expression);
    ((IQueryable<Hall>)dbSet).ElementType.Returns(items.ElementType);
    ((IQueryable<Hall>)dbSet).GetEnumerator().Returns(items.GetEnumerator());
    dbContext.Halls = dbSet;

    return dbContext;
}

NB: the line that states: dbContext.Halls = dbSet instead of dbContext.Set<Strategy>().Returns(dbSet);

Upvotes: 0

Related Questions