NBuilder 和 DbContext 无效转换问题
NBuilder and DbContext invalid cast issue
我是 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 : Unable to cast object of type 'Castle.Proxies.ObjectProxy' to type 'Microsoft.EntityFrameworkCore.Metadata.Internal.Model'.
有谁知道我可以做些什么来让它工作?
所以我发现了这个问题:
而且我已将方法更改为:
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;
}
但我仍然得到同样的错误....
第二个解决方案非常接近,就是这样:
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<Strategy>().Returns(dbSet);
我是 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 : Unable to cast object of type 'Castle.Proxies.ObjectProxy' to type 'Microsoft.EntityFrameworkCore.Metadata.Internal.Model'.
有谁知道我可以做些什么来让它工作?
所以我发现了这个问题:
而且我已将方法更改为:
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;
}
但我仍然得到同样的错误....
第二个解决方案非常接近,就是这样:
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<Strategy>().Returns(dbSet);