【问题标题】:NBuilder and DbContext invalid cast issueNBuilder 和 DbContext 无效转换问题
【发布时间】:2020-01-25 20:47:08
【问题描述】:

我真的是 NBuilder 的新手,但它看起来很棒,所以我想我会尝试一下。 我有一个DatabaseContext,它只是继承自DbContext,如下所示:

public class DatabaseContext : DbContext

现在,我创建了一个像这样查询DatabaseContext 的服务:

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

现在我想做一个测试。 我这样设置这个上下文:

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);
}

最重要的部分是CreateDatabaseContext 方法。 是这样的:

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

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

    return dbContext;
}

但是当我运行测试时,我得到了这个错误:

System.InvalidCastException:无法将“Castle.Proxies.ObjectProxy”类型的对象转换为“Microsoft.EntityFrameworkCore.Metadata.Internal.Model”类型。

有谁知道我可以做些什么来让它工作?


所以我发现了这个问题: How do I mock DbContext using NSubstitute and then add/remove data

我已经将我的方法更改为:

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;
}

但我仍然遇到同样的错误......

【问题讨论】:

    标签: nunit dbcontext nsubstitute nbuilder


    【解决方案1】:

    第二个解决方案非常接近,就是这样:

    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;
    }
    

    注意:声明的行:dbContext.Halls = dbSet 而不是 dbContext.Set&lt;Strategy&gt;().Returns(dbSet);

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-05-07
      • 1970-01-01
      • 2019-09-08
      • 2012-11-10
      相关资源
      最近更新 更多